@@ -165,17 +165,21 @@ system::result<T> channel<T>::read_op::await_resume(const struct as_result_tag &
165
165
if (cancelled)
166
166
return {system ::in_place_error, asio::error::operation_aborted};
167
167
168
- T value = direct ? std::move (*direct) : std::move (chn->buffer_ .front ());
169
- if (!direct)
168
+ T value = chn->buffer_ .empty () ? std::move (*direct) : std::move (chn->buffer_ .front ());
169
+ if (!chn->buffer_ .empty ())
170
+ {
170
171
chn->buffer_ .pop_front ();
172
+ if (direct)
173
+ chn->buffer_ .push_back (std::move (*direct));
174
+ }
171
175
172
176
if (!chn->write_queue_ .empty ())
173
177
{
174
178
auto &op = chn->write_queue_ .front ();
175
179
BOOST_ASSERT (chn->read_queue_ .empty ());
176
180
if (op.await_ready ())
177
181
{
178
- op.transactional_unlink ();
182
+ op.unlink ();
179
183
BOOST_ASSERT (op.awaited_from );
180
184
asio::post (chn->executor_ , std::move (op.awaited_from ));
181
185
}
@@ -211,6 +215,7 @@ std::coroutine_handle<void> channel<T>::write_op::await_suspend(std::coroutine_h
211
215
if constexpr (requires (Promise p) {p.begin_transaction ();})
212
216
begin_transaction = +[](void * p){std::coroutine_handle<Promise>::from_address (p).promise ().begin_transaction ();};
213
217
218
+ BOOST_ASSERT (this ->chn ->buffer_ .full ());
214
219
if (chn->read_queue_ .empty ())
215
220
{
216
221
chn->write_queue_ .push_back (*this );
@@ -259,7 +264,7 @@ system::result<void> channel<T>::write_op::await_resume(const struct as_result_
259
264
if (cancel_slot.is_connected ())
260
265
cancel_slot.clear ();
261
266
if (cancelled)
262
- boost::throw_exception ( system ::system_error ( asio::error::operation_aborted), loc) ;
267
+ return { system ::in_place_error, asio::error::operation_aborted} ;
263
268
264
269
if (!direct)
265
270
{
@@ -281,7 +286,8 @@ system::result<void> channel<T>::write_op::await_resume(const struct as_result_
281
286
BOOST_ASSERT (chn->write_queue_ .empty ());
282
287
if (op.await_ready ())
283
288
{
284
- op.transactional_unlink ();
289
+ // unlink?
290
+ op.unlink ();
285
291
BOOST_ASSERT (op.awaited_from );
286
292
asio::post (chn->executor_ , std::move (op.awaited_from ));
287
293
}
@@ -297,7 +303,8 @@ struct channel<void>::read_op::cancel_impl
297
303
{
298
304
op->cancelled = true ;
299
305
op->unlink ();
300
- asio::post (op->chn ->executor_ , std::move (op->awaited_from ));
306
+ if (op->awaited_from )
307
+ asio::post (op->chn ->executor_ , std::move (op->awaited_from ));
301
308
op->cancel_slot .clear ();
302
309
}
303
310
};
@@ -310,7 +317,8 @@ struct channel<void>::write_op::cancel_impl
310
317
{
311
318
op->cancelled = true ;
312
319
op->unlink ();
313
- asio::post (op->chn ->executor_ , std::move (op->awaited_from ));
320
+ if (op->awaited_from )
321
+ asio::post (op->chn ->executor_ , std::move (op->awaited_from ));
314
322
op->cancel_slot .clear ();
315
323
}
316
324
};
@@ -322,6 +330,8 @@ std::coroutine_handle<void> channel<void>::read_op::await_suspend(std::coroutine
322
330
if ((cancel_slot = h.promise ().get_cancellation_slot ()).is_connected ())
323
331
cancel_slot.emplace <cancel_impl>(this );
324
332
333
+ if (awaited_from)
334
+ boost::throw_exception (std::runtime_error (" already-awaited" ), loc);
325
335
awaited_from.reset (h.address ());
326
336
327
337
if constexpr (requires (Promise p) {p.begin_transaction ();})
0 commit comments