Boost C++ 库

……该库是全球备受推崇且设计精良的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu《C++ 编码标准》

co_composed - Boost C++ 函数库
PrevUpHomeNext

创建一个可用于启动基于协程的复合异步操作的初始化函数对象。

template<
    typename... Signatures,
    typename Implementation,
    typename... IoObjectsOrExecutors>
auto co_composed(
    Implementation && implementation,
    IoObjectsOrExecutors &&... io_objects_or_executors);

co_composed 工具通过自动适配协程以使其成为可与 async_initiate 一起使用的初始化函数对象,从而简化了复合异步操作的实现。在等待异步操作时,协程会自动使用符合要求的中间完成处理程序。

参数

implementation

一个函数对象,其中包含基于协程的复合异步操作的实现。函数对象的第一个参数代表操作的状态,可用于测试取消。其余参数是在完成令牌之后传递给 async_initiate 的参数。

io_objects_or_executors

零个或多个 I/O 对象或 I/O 执行器,在操作未完成期间必须维护其上的挂起工作。

按操作取消

默认情况下,对于使用 co_composed 的复合操作,会启用终端按操作取消。要禁用复合操作的取消,或更改其支持的取消类型,请调用状态的 reset_cancellation_state 函数。

示例

以下示例说明了手动错误处理和显式取消检查。完成处理程序通过对状态的 complete 函数进行 co_yield 来调用,该函数永远不会返回。

template <typename CompletionToken>
auto async_echo(tcp::socket& socket,
    CompletionToken&& token)
{
  return boost::asio::async_initiate<
    CompletionToken, void(boost::system::error_code)>(
      boost::asio::co_composed(
        [](auto state, tcp::socket& socket) -> void
        {
          state.reset_cancellation_state(
            boost::asio::enable_terminal_cancellation());

          while (!state.cancelled())
          {
            char data[1024];
            auto [e1, n1] =
              co_await socket.async_read_some(
                boost::asio::buffer(data));

            if (e1)
              co_yield state.complete(e1);

            if (!!state.cancelled())
              co_yield state.complete(
                make_error_code(boost::asio::error::operation_aborted));

            auto [e2, n2] =
              co_await boost::asio::async_write(socket,
                boost::asio::buffer(data, n1));

            if (e2)
              co_yield state.complete(e2);
          }
        }, socket),
      token, std::ref(socket));
}

下一个示例展示了基于异常的错误处理和隐式取消检查。通过从协程返回后,使用 co_return 调用完成处理程序。有效的 co_return 值使用传递给 co_composed 函数的完成签名进行指定。

template <typename CompletionToken>
auto async_echo(tcp::socket& socket,
    CompletionToken&& token)
{
  return boost::asio::async_initiate<
    CompletionToken, void(boost::system::error_code)>(
      boost::asio::co_composed<
        void(boost::system::error_code)>(
          [](auto state, tcp::socket& socket) -> void
          {
            try
            {
              state.throw_if_cancelled(true);
              state.reset_cancellation_state(
                boost::asio::enable_terminal_cancellation());

              for (;;)
              {
                char data[1024];
                std::size_t n = co_await socket.async_read_some(
                    boost::asio::buffer(data));

                co_await boost::asio::async_write(socket,
                    boost::asio::buffer(data, n));
              }
            }
            catch (const boost::system::system_error& e)
            {
              co_return {e.code()};
            }
          }, socket),
      token, std::ref(socket));
}
要求

Header: boost/asio/co_composed.hpp

便捷头文件: boost/asio.hpp


PrevUpHomeNext