Skip to content

Commit 53611b9

Browse files
fixed channel race condition.
1 parent 57181ca commit 53611b9

File tree

3 files changed

+56
-35
lines changed

3 files changed

+56
-35
lines changed

include/boost/cobalt/impl/channel.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,19 @@ system::result<T> channel<T>::read_op::await_resume(const struct as_result_tag &
193193
if (op.await_ready())
194194
{
195195
op.unlink();
196+
if (!op.cancelled && !op.closed)
197+
{
198+
op.direct = true;
199+
if constexpr (std::is_copy_constructible_v<T>)
200+
{
201+
if (op.ref.index() == 0)
202+
chn->buffer_.push_back(std::move(*variant2::get<0>(op.ref)));
203+
else
204+
chn->buffer_.push_back(*variant2::get<1>(op.ref));
205+
}
206+
else
207+
chn->buffer_.push_back(std::move(*op.ref));
208+
}
196209
BOOST_ASSERT(op.awaited_from);
197210
asio::post(chn->executor_, std::move(op.awaited_from));
198211
}

src/channel.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ system::result<void> channel<void>::read_op::await_resume(const struct as_resul
7171
if (op.await_ready())
7272
{
7373
op.unlink();
74+
if (!op.cancelled && !op.closed)
75+
{
76+
op.direct = true;
77+
chn->n_++;
78+
}
7479
BOOST_ASSERT(op.awaited_from);
7580
asio::post(chn->executor_, std::move(op.awaited_from));
7681
}

test/channel.cpp

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <boost/test/unit_test.hpp>
1919
#include <any>
2020

21+
#include <boost/asio/detached.hpp>
22+
2123
namespace cobalt = boost::cobalt;
2224

2325
cobalt::promise<void> do_write(cobalt::channel<void> &chn, std::vector<int> & seq)
@@ -57,22 +59,22 @@ CO_TEST_CASE(void_)
5759
co_await r;
5860
co_await w;
5961
BOOST_REQUIRE(seq.size() == 16);
60-
BOOST_CHECK(seq[0] == 10);
61-
BOOST_CHECK(seq[1] == 0);
62-
BOOST_CHECK(seq[2] == 1);
63-
BOOST_CHECK(seq[3] == 2);
64-
BOOST_CHECK(seq[4] == 11);
65-
BOOST_CHECK(seq[5] == 12);
66-
BOOST_CHECK(seq[6] == 3);
67-
BOOST_CHECK(seq[7] == 4);
68-
BOOST_CHECK(seq[8] == 13);
69-
BOOST_CHECK(seq[9] == 14);
70-
BOOST_CHECK(seq[10] == 5);
71-
BOOST_CHECK(seq[11] == 6);
72-
BOOST_CHECK(seq[12] == 15);
73-
BOOST_CHECK(seq[13] == 16);
74-
BOOST_CHECK(seq[14] == 7);
75-
BOOST_CHECK(seq[15] == 17);
62+
BOOST_CHECK_EQUAL(seq[0], 10);
63+
BOOST_CHECK_EQUAL(seq[1], 0);
64+
BOOST_CHECK_EQUAL(seq[2], 1);
65+
BOOST_CHECK_EQUAL(seq[3], 2);
66+
BOOST_CHECK_EQUAL(seq[4], 11);
67+
BOOST_CHECK_EQUAL(seq[5], 12);
68+
BOOST_CHECK_EQUAL(seq[6], 13);
69+
BOOST_CHECK_EQUAL(seq[7], 3);
70+
BOOST_CHECK_EQUAL(seq[8], 4);
71+
BOOST_CHECK_EQUAL(seq[9], 5);
72+
BOOST_CHECK_EQUAL(seq[10], 14);
73+
BOOST_CHECK_EQUAL(seq[11], 15);
74+
BOOST_CHECK_EQUAL(seq[12], 16);
75+
BOOST_CHECK_EQUAL(seq[13], 6);
76+
BOOST_CHECK_EQUAL(seq[14], 7);
77+
BOOST_CHECK_EQUAL(seq[15], 17);
7678
}
7779

7880
CO_TEST_CASE(void_0)
@@ -140,22 +142,22 @@ CO_TEST_CASE(int_)
140142
co_await r;
141143
co_await w;
142144
BOOST_REQUIRE(seq.size() == 16);
143-
BOOST_CHECK(seq[0] == 0);
144-
BOOST_CHECK(seq[1] == 1);
145-
BOOST_CHECK(seq[2] == 2);
146-
BOOST_CHECK(seq[3] == 10);
147-
BOOST_CHECK(seq[4] == 11);
148-
BOOST_CHECK(seq[5] == 12);
149-
BOOST_CHECK(seq[6] == 3);
150-
BOOST_CHECK(seq[7] == 4);
151-
BOOST_CHECK(seq[8] == 13);
152-
BOOST_CHECK(seq[9] == 14);
153-
BOOST_CHECK(seq[10] == 5);
154-
BOOST_CHECK(seq[11] == 6);
155-
BOOST_CHECK(seq[12] == 15);
156-
BOOST_CHECK(seq[13] == 16);
157-
BOOST_CHECK(seq[14] == 7);
158-
BOOST_CHECK(seq[15] == 17);
145+
BOOST_CHECK_EQUAL(seq[0], 0);
146+
BOOST_CHECK_EQUAL(seq[1], 1);
147+
BOOST_CHECK_EQUAL(seq[2], 2);
148+
BOOST_CHECK_EQUAL(seq[3], 10);
149+
BOOST_CHECK_EQUAL(seq[4], 11);
150+
BOOST_CHECK_EQUAL(seq[5], 12);
151+
BOOST_CHECK_EQUAL(seq[6], 13);
152+
BOOST_CHECK_EQUAL(seq[7], 3);
153+
BOOST_CHECK_EQUAL(seq[8], 4);
154+
BOOST_CHECK_EQUAL(seq[9], 5);
155+
BOOST_CHECK_EQUAL(seq[10], 14);
156+
BOOST_CHECK_EQUAL(seq[11], 15);
157+
BOOST_CHECK_EQUAL(seq[12], 16);
158+
BOOST_CHECK_EQUAL(seq[13], 6);
159+
BOOST_CHECK_EQUAL(seq[14], 7);
160+
BOOST_CHECK_EQUAL(seq[15], 17);
159161
}
160162

161163
cobalt::promise<void> do_write(cobalt::channel<std::string> &chn, std::vector<int> & seq)
@@ -378,8 +380,9 @@ CO_TEST_CASE(interrupt_1)
378380
lr = co_await cobalt::left_race(c.write(43), c.read());
379381
BOOST_CHECK(lr.index() == 1);
380382
BOOST_CHECK(get<1u>(lr) == 42);
381-
auto rl = co_await cobalt::left_race(c.read(), c.write(42));
382-
BOOST_CHECK(rl.index() == 1);
383+
auto rl = co_await cobalt::left_race(c.read(), c.write(44));
384+
BOOST_CHECK(rl.index() == 0);
385+
BOOST_CHECK_EQUAL(get<0u>(rl) , 43);
383386
}
384387

385388
CO_TEST_CASE(interrupt_void_1)
@@ -390,7 +393,7 @@ CO_TEST_CASE(interrupt_void_1)
390393
lr = co_await cobalt::left_race(c.write(), c.read());
391394
BOOST_CHECK(lr == 1);
392395
auto rl = co_await cobalt::left_race(c.read(), c.write());
393-
BOOST_CHECK(rl == 1);
396+
BOOST_CHECK(rl == 0);
394397
}
395398

396399

0 commit comments

Comments
 (0)