我正在尝试在现有代码库的深处添加一些异步操作,这些操作在使用 pion 实现的 Web 服务器中调用(它本身使用 boost::asio)。
当前代码需要在没有 io_service 可用的上下文中继续运行,所以我做了以下操作,其中 Foo::bar 是现有代码库的主要入口点,handleRequest 是 pion 请求处理程序:
class Foo
{
public:
void bar(std::string input, boost::asio::io_service* io = NULL)
{
ioService = io;
if ( io == NULL )
{
barCommon(input);
}
else
{
boost::asio::spawn(*io, boost::bind(&Foo::barAsync, this, input, _1));
}
}
void barAsync(std::string input, boost::asio::yield_context yc)
{
barCommon(input, &yc);
}
void barCommon(std::string input, boost::asio::yield_context* yieldContext = NULL)
{
// Existing code here, with some operations performed async
// using ioService and yieldContext if they are not NULL.
}
private:
boost::asio::io_service* ioService;
// Other member variables, which cause a crash when accessed
}
void handleRequest(pion::http::request_ptr request, pion::tcp::connection_ptr connection)
{
Foo* foo = acquireFooPointer();
foo->bar(std::string(request->get_content()), &connection->get_io_service());
}
这似乎有效,因为它最终在协程中运行 Foo::barCommon,但是现有代码一旦尝试访问 Foo 成员变量就会崩溃。我在这里想念什么?
编辑:为了清楚起见,handleRequest 中获取的指针指向一个堆分配的 Foo 对象,其生命周期与服务器进程的生命周期相匹配。