Skip to content

Commit 2957ffe

Browse files
committed
asioexec::completion_token: Lvalue Completion Handler Invocation
As added by 35a3e31 the completion handler type used by the implementation of asioexec::completion_token only supported rvalue-qualified invocation. This was due to the fact: - Invocation of a completion handler is consumptive in the same way that calling set_value, set_error, or set_stopped on a receiver is (note those three operations require an rvalue-qualified operand), and - Asio has invoked completion handlers with rvalue qualification since 1.20.0 (standalone)/1.77 (Boost) Unfortunately there are operations in the wild which do not rvalue qualify their completion handlers when invoking them. For example the operations provided by Boost.Beast (at least as of this writing). Updated asioexec::completion_token to support the above-described operations by removing the rvalue qualification from the function call operator of its completion handler type.
1 parent cc8e3aa commit 2957ffe

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

include/asioexec/completion_token.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ namespace asioexec {
244244
}
245245

246246
template <typename... Args>
247-
void operator()(Args&&... args) && noexcept {
247+
void operator()(Args&&... args) noexcept {
248248
STDEXEC_ASSERT(self_);
249249
{
250250
const std::lock_guard l(self_->m_);

test/asioexec/test_completion_token.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,4 +718,15 @@ namespace {
718718
CHECK(lvalue_kind == value_category_receiver::kind::const_lvalue);
719719
}
720720

721+
TEST_CASE(
722+
"Lvalue invocation of the completion handler is supported (for compatibility with Boost.Beast "
723+
"perhaps among others)",
724+
"[asioexec][completion_token]") {
725+
const auto initiating_function = [](auto&& token) {
726+
return asio_impl::async_initiate<decltype(token), void()>([](auto&& h) { h(); }, token);
727+
};
728+
auto op = ::stdexec::connect(initiating_function(completion_token), expect_value_receiver{});
729+
::stdexec::start(op);
730+
}
731+
721732
} // namespace

0 commit comments

Comments
 (0)