2
0
mirror of https://github.com/boostorg/asio.git synced 2026-02-26 14:52:09 +00:00
Commit Graph

1654 Commits

Author SHA1 Message Date
Christopher Kohlhoff
f6d3a8c2ef Version bump. 2021-07-15 12:03:16 +10:00
Christopher Kohlhoff
a51b9b8198 Ensure un-cancelled ops are correctly placed back in the queue. 2021-07-11 22:03:29 +10:00
Christopher Kohlhoff
aafa4c6471 Document supported cancellation types. 2021-07-11 19:12:44 +10:00
Christopher Kohlhoff
2f207559f0 Fix compatibility with recent LibreSSL when OPENSSL_NO_SSL_INTERN is defined. 2021-07-11 16:45:55 +10:00
Christopher Kohlhoff
455729198e Disable coroutines support for the clang shipped with MSVC. 2021-07-11 16:45:42 +10:00
Christopher Kohlhoff
eb33daf680 Ensure gcc tests are not used for clang when detecting compiler/language features. 2021-07-11 16:45:12 +10:00
Christopher Kohlhoff
649dde15c9 Ensure handler alignment requirements are respected by cancellation_signal. 2021-07-11 10:20:19 +10:00
Christopher Kohlhoff
310dcb34b2 Fix order of _aligned_malloc arguments for MSVC. 2021-07-11 10:20:19 +10:00
Christopher Kohlhoff
99ebe28a64 Fix strand<> to avoid using a potentially moved-from executor. 2021-07-11 10:20:19 +10:00
Christopher Kohlhoff
c1fd78e785 Fix handling of move-only results with awaitable operators && and ||. 2021-07-11 10:20:19 +10:00
Christopher Kohlhoff
2de6076965 Add revision history. 2021-07-08 13:14:38 +10:00
Christopher Kohlhoff
ef4e3d873c Add missing #includes for when using separate compilation. 2021-07-08 13:14:30 +10:00
Christopher Kohlhoff
c47d0007c5 Exclude is_deferred trait specialisations from the docs. 2021-07-08 00:50:38 +10:00
Christopher Kohlhoff
17ef2577d8 Fix this_coro::throw_if_cancelled link in reference index. 2021-07-07 23:52:08 +10:00
Christopher Kohlhoff
8f6bdef9e5 Version bump. 2021-07-07 22:47:51 +10:00
Christopher Kohlhoff
0729e41f99 Regenerate documentation. 2021-07-07 22:47:10 +10:00
Christopher Kohlhoff
fc486d6530 Fix failure in coro simple_test. 2021-07-07 22:47:10 +10:00
Christopher Kohlhoff
0cc4c7093a Clean up doc generation to accommodate new features. 2021-07-07 22:47:10 +10:00
Christopher Kohlhoff
9cc511935c Experimental features don't have convenience headers. 2021-07-07 22:47:10 +10:00
Christopher Kohlhoff
15b4f0eee2 Add new experimental facilities to the quick reference. 2021-07-07 22:47:10 +10:00
Christopher Kohlhoff
1570d3c352 Clean up source code for doxygen generation. 2021-07-07 20:21:14 +10:00
Christopher Kohlhoff
837f789484 Apply cancellation to a restarted AcceptEx operation. 2021-07-07 17:34:41 +10:00
Christopher Kohlhoff
87b84d2d1b Add cancellation slot support to IOCP sockets when using reactor-based operations. 2021-07-06 00:45:22 +10:00
Christopher Kohlhoff
4ca5e6a13a Make promise test more resistant to a heavily loaded test system. 2021-07-05 18:45:03 +10:00
Christopher Kohlhoff
77cf53057c Fix return_void() in experimental::coro. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
1961a5ca2a Fix execution_context concept definition. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
9134e26afe Remove unused lambda capture. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
769dc0e149 Add this_coro::throw_if_cancelled.
By default, awaitable<>-based coroutines now throw an exception if they
have been previously cancelled, and then try to perform a co_await
against another awaitable<>.

To disable this behaviour for the current awaitable<>-based "thread",
perform:

    co_await boost::asio::this_coro::throw_if_error(false);

It is then the responsibility of the coroutine implementation to ensure
that it checks the cancellation state of the coroutine manually, by
doing something like:

    auto cs = boost::asio::this_coro::cancellation_state;
    // ...
    if (cs.cancelled() != cancellation_type::none)
    {
      // ... handle cancellation ...
    }
2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
e711511742 Fixes for experimental::coro when using gcc 11. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
8c56568e3b Store awaitable_thread state in the bottom-of-stack promise. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
d2ab7b7669 Fix yield input in experimental::coro. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
386f7bac93 Add cancellation_slot support to IOCP-based handle operations. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
4b21d8768c Add cancellation_slot support to IOCP-based socket operations. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
01ca2be880 Ensure experimental::deferred header is self-contained. 2021-07-04 13:10:27 +10:00
Christopher Kohlhoff
f486b43c16 Add operator&& and operator|| for awaitable<>.
The logical operators || and && have been overloaded for awaitable<>, to
allow coroutines to be trivially awaited in parallel.

When awaited using &&, the await expression waits until both operations
have completed successfully. As a "short-circuit" evaluation, if one
operation fails with an exception, the other is immediately cancelled.
For example:

    std::tuple<std::size_t, std::size_t> results =
      co_await (
        async_read(socket, input_buffer, use_awaitable)
          && async_write(socket, output_buffer, use_awaitable)
      );

When awaited using ||, the await expression waits until either operation
succceeds. As a "short-circuit" evaluation, if one operation succeeds
without throwing an exception, the other is immediately cancelled. For
example:

    std::variant<std::size_t, std::monostate> results =
      co_await (
        async_read(socket, input_buffer, use_awaitable)
          || timer.async_wait(use_awaitable)
      );

The operators may be enabled by adding the #include:

    #include <asio/experimental/awaitable_operators.hpp>

and then bringing the contents of the experimental::awaitable_operators
namespace into scope:

    using namespace boost::asio::experimental::awaitable_operators;
2021-07-04 13:05:46 +10:00
Christopher Kohlhoff
a8c7e7e8c1 Add missing #includes, destructor. 2021-07-04 13:03:06 +10:00
Christopher Kohlhoff
fb5311480d Change to co_spawn to dispatch first and only post if the coroutine did not context-switch. 2021-07-04 13:02:54 +10:00
Christopher Kohlhoff
9b3fc2ef83 Add move assignment to ssl::stream<>. 2021-07-02 12:29:57 +10:00
klemens-morgenstern
ecca8406c0 Added experimental::coro class template.
The coro type is a C++20 coroutine primitive for resumable functions,
with the ability to combine both asynchronous waiting (co_await) and
yielding (co_yield) into a single, stateful control flow. For example:

    #include <boostasio.hpp>
    #include <boostasio/experimental/coro.hpp>

    using boost::asio::ip::tcp;

    boost::asio::experimental::coro<std::string> reader(tcp::socket& sock)
    {
      std::string buf;
      while (sock.is_open())
      {
        std::size_t n = co_await boost::asio::async_read_until(
            sock, boost::asio::dynamic_buffer(buf), '\n',
            boost::asio::experimental::use_coro);
        co_yield buf.substr(0, n);
        buf.erase(0, n);
      }
    }

    boost::asio::awaitable<void> consumer(tcp::socket sock)
    {
      auto r = reader(sock);
      auto msg1 = co_await r.async_resume(boost::asio::use_awaitable);
      std::cout << "Message 1: " << msg1.value_or("\n");
      auto msg2 = co_await r.async_resume(boost::asio::use_awaitable);
      std::cout << "Message 2: " << msg2.value_or("\n");
    }

    boost::asio::awaitable<void> listen(tcp::acceptor& acceptor)
    {
      for (;;)
      {
        co_spawn(
            acceptor.get_executor(),
            consumer(co_await acceptor.async_accept(boost::asio::use_awaitable)),
            boost::asio::detached);
      }
    }

    int main()
    {
      boost::asio::io_context ctx;
      tcp::acceptor acceptor(ctx, {tcp::v4(), 54321});
      co_spawn(ctx, listen(acceptor), boost::asio::detached);
      ctx.run();
    }
2021-07-01 21:34:51 +10:00
klemens-morgenstern
03ba758437 Added experimental::promise.
The experimental::promise type allows eager execution and
synchronisation of async operations.

    auto promise = async_read(
        stream, asio::buffer(my_buffer),
        asio::experimental::use_promise);

    ... do other stuff while the read is going on ...

    promise.async_wait( // completion the operation
        [](error_code ec, std::size_t bytes_read)
        {
          ...
        });

Promises can be safely disregarded if the result is no longer required.

Different operations can be combined to either wait for all to complete
or for one to complete (and cancel the rest). For example, to wait for
one to complete:

    auto timeout_promise =
      timer.async_wait(
        asio::experimental::use_promise);

    auto read_promise = async_read(
        stream, asio::buffer(my_buffer),
        asio::experimental::use_promise);

    auto promise =
      asio::experimental::promise<>::race(
        timeout_promise, read_promise);

    promise.async_wait(
        [](std::variant<error_code, std::tuple<error_code, std::size_t>> v)
        {
          if (v.index() == 0) {} //timed out
          else if (v.index() == 1) // completed in time
        });

or to wait for all to complete:

    auto write_promise = async_write(
        stream, asio::buffer(my_write_buffer),
        asio::experimental::use_promise);

    auto read_promise = async_read(
        stream, asio::buffer(my_buffer),
        asio::experimental::use_promise);

    auto promise =
      asio::experimental::promise<>::all(
        write_promise, read_promise);

    promise.async_wait(
        [](std::tuple<error_code, std::size_t> write_result,
          std::tuple<error_code, std::size_t> read_result)
        {
        });
2021-07-01 15:40:28 +10:00
Christopher Kohlhoff
1c3c80d778 Make experimental::parallel_group compatible with C++14. 2021-07-01 10:52:01 +10:00
Christopher Kohlhoff
66b41bff1c Ensure all aligned allocations' sizes are a multiple of the alignment. 2021-07-01 10:52:01 +10:00
Christopher Kohlhoff
5145c8f83d Add self-container-header checks for cancellation functionality. 2021-07-01 10:52:01 +10:00
Christopher Kohlhoff
909f7ee6c0 Fix long lines. 2021-07-01 10:52:01 +10:00
Christopher Kohlhoff
0c340c786a Add experimental::deferred completion token.
The experimental::deferred completion token takes a call to an
asynchronous operation's initiating function and turns it into a
function object that accepts a completion token. For example:

  auto deferred_op =
    timer.async_wait(
      boost::asio::experimental::deferred);
  ...
  std::move(deferred_op)(
      [](std::error_code ec){ ... });

or

  auto deferred_op =
    timer.async_wait(
      boost::asio::experimental::deferred);
  ...
  std::future<void> =
    std::move(deferred_op)(
      boost::asio::use_future);

The deferred token also supports chaining, to create simple
compositions:

  auto deferred_op =
    timer.async_wait(
      boost::asio::experimental::deferred(
        [&](std::error_code ec)
        {
          timer.expires_after(
              std::chrono::seconds(1));

          return timer.async_wait(
              boost::asio::experimental::deferred);
        });
  ...
  std::future<void> = std::move(deferred_op)(boost::asio::use_future);
2021-07-01 10:52:01 +10:00
Christopher Kohlhoff
b899f98566 Add experimental::prepend completion token adapter.
The prepend completion token adapter can be used to pass additional
before the existing completion handler arguments. For example:

  timer.async_wait(
      boost::asio::experimental::prepend(
        [](int i, std::error_code ec)
        {
          // ...
        },
      42)
    );

  std::future<std::tuple<int, std::error_code>> f = timer.async_wait(
      boost::asio::experimental::prepend(
        boost::asio::use_future,
        42
      )
    );
2021-07-01 10:51:52 +10:00
Christopher Kohlhoff
560446b93e Fix return type deduction in experimental::append. 2021-07-01 10:13:48 +10:00
Christopher Kohlhoff
d18260d8e0 Initial implementation of parallel_group. 2021-07-01 10:12:53 +10:00
Christopher Kohlhoff
aa52f655e7 Add cancellation-related type requirements to quick reference. 2021-07-01 10:10:41 +10:00
Christopher Kohlhoff
2967887681 Fix CancellationSlot requirements table caption. 2021-07-01 10:08:52 +10:00