gpt4 book ai didi

c++ - boost_asio_handler_invoke_helpers::invoke 是否仍然是在 boost asio 1.70 中调用完成处理程序的受支持方式?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:38:14 25 4
gpt4 key购买 nike

我正在使用 asio 将代码从 boost 1.65.1 迁移到 1.70.0。有一个使用 boost_asio_handler_invoke_helpers::invoke 的代码,它似乎不像以前的版本那样工作。

我发现了这个问题 https://github.com/boostorg/asio/issues/79在 github 上解释了 executor_binder 是如何工作的。所以在这种情况下,旧的 asio_handler_invoke 函数似乎不再起作用。

class callback_service {
public:
void run() {
if (callback_) callback_();
}

void subscribe(std::function<void(void)> callback) {
callback_ = std::move(callback);
}

private:
std::function<void(void)> callback_;
};

template <typename CompletionToken>
auto async_wait_callback(callback_service& service, CompletionToken&& token)
{
return boost::asio::async_initiate<CompletionToken, void(void)>(
[] (auto&& completion_handler, callback_service& s) {
s.subscribe([h=std::move(completion_handler)] () mutable {

// Is this still worked in 1.70 ?
boost_asio_handler_invoke_helpers::invoke(h, h);
});
},
token, std::ref(service));
}

BOOST_AUTO_TEST_CASE(test_async_wait_callback)
{
boost::asio::io_context ioc;
auto work = boost::asio::make_work_guard(ioc);

callback_service service;

boost::asio::spawn(ioc, [&] (boost::asio::yield_context yield) {
const auto initiate_thread_id = std::this_thread::get_id();

boost::asio::post(ioc, [&] {
// call the completion handler from another thread.
std::thread t([&] {
service.run();
});
t.join();
});

async_wait_callback(service, yield);

// Check if we resume in the correct execution context.
BOOST_CHECK_EQUAL(initiate_thread_id, std::this_thread::get_id());
ioc.stop();
});

ioc.run();
}

测试代码因该错误而失败

Running 1 test case...
error: in "test_async_wait_callback": check initiate_thread_id == std::this_thread::get_id() has failed [10912 != 26444]

这意味着堆栈协程没有在正确的执行上下文中恢复。

最佳答案

我当前的解决方法是通过 get_associated_executor 调度旧回调。

template <typename CompletionToken>
auto async_wait_callback(callback_service& service, CompletionToken&& token)
{
return boost::asio::async_initiate<CompletionToken, void(void)>(
[] (auto&& completion_handler, callback_service& s) {
s.subscribe([h=std::move(completion_handler)] () mutable {
auto ex = boost::asio::get_associated_executor(h);
boost::asio::dispatch(ex, [h=std::move(h)] () mutable {
boost_asio_handler_invoke_helpers::invoke(h, h);
});
});
},
token, std::ref(service));
}

关于c++ - boost_asio_handler_invoke_helpers::invoke 是否仍然是在 boost asio 1.70 中调用完成处理程序的受支持方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57405554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com