2

我正在尝试在现有代码库的深处添加一些异步操作,这些操作在使用 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 对象,其生命周期与服务器进程的生命周期相匹配。

4

0 回答 0