96 Commits

Author SHA1 Message Date
Christopher Kohlhoff e385df66bd Update copyright notices. 2026-03-03 20:45:33 +11:00
Christopher Kohlhoff f49a0add53 Add redirect_disposition completion token adapter. 2025-11-04 23:42:51 +11:00
Christopher Kohlhoff 5fa261e86d Add inline_or_executor<> and inline_or(). 2025-10-30 08:28:04 +11:00
Christopher Kohlhoff 84c45dbe48 Add inline_executor. 2025-10-29 22:58:47 +11:00
Christopher Kohlhoff 82c9b858c8 Add execution::inline_exception_handling property. 2025-10-29 22:57:58 +11:00
Christopher Kohlhoff 1afbc5c12b Update copyright notices. 2025-03-04 22:57:26 +11:00
Christopher Kohlhoff b0fe7b2df8 Add disposition requirements to the documentation. 2024-10-31 20:31:20 +11:00
Christopher Kohlhoff bbda620590 Add asio::config.
The asio::config class provides access to configuration variables that
are associated with an execution context. The class is intended for use
by asio internals, or by libraries or user-provided abstractions that
build on top of asio. These configuration variables will typically be
used to fine tune behaviour, such as enabling or disabling certain
optimisations.

When constructing an execution context, such as an io_context, the
caller may optionally pass a service_maker to install a concrete
configuration service into the context. For example:

  asio::io_context ctx{asio::config_from_env{}};

The configuration variables' values are accessed by using the
asio::config class, passing a section, key and default value:

  asio::config cfg{ctx};
  bool enable_locking = cfg.get("scheduler", "locking", true);

The initial set of configuration variables recognised by the asio
internals correspond to the concurrency hint and its special values:

  "scheduler" / "concurrency_hint" (int)
  "scheduler" / "locking" (bool)
  "reactor" / "registration_locking" (bool)
  "reactor" / "io_locking" (bool)
2024-10-30 23:01:37 +11:00
Christopher Kohlhoff dc8dc3e192 Add execution_context::service_maker abstract base class.
A service_maker is an object that is passed to an execution context's
constructor, and allows services to be added at context construction
time. Additional constructor overloads have been added to io_context and
thread_pool that accept a service_maker. For example:

  class my_service_maker : public execution_context::service_maker
  {
  public:
    void make(execution_context& ctx) override
    {
      make_service<my_service>(ctx);
    }
  };

  io_context ctx{my_service_maker{}};
2024-10-30 23:00:28 +11:00
Christopher Kohlhoff 6e4171839e Deprecate deadline_timer and associated types. 2024-10-23 21:21:20 +11:00
Christopher Kohlhoff bc417934ec Deprecate basic_io_object. 2024-10-23 21:21:02 +11:00
Christopher Kohlhoff 3490144b26 Remove deprecated class io_context::work. 2024-10-23 21:18:50 +11:00
Christopher Kohlhoff 995eeab569 Remove deprecated class ssl::rfc2818_verification. 2024-10-23 21:18:09 +11:00
Christopher Kohlhoff 7d1aac2ffd Remove deprecated function buffer_cast. 2024-10-23 21:12:02 +11:00
Christopher Kohlhoff 534a48c0d5 Remove deprecated classes const_buffers_1 and mutable_buffers_1. 2024-10-23 21:10:47 +11:00
Christopher Kohlhoff bee30415e8 Update quick reference. 2024-07-09 22:05:30 +10:00
Christopher Kohlhoff 5c01494f70 Promote co_composed to the asio namespace. 2024-07-02 07:54:20 +10:00
Christopher Kohlhoff 44b433abc7 Tidy up quick reference. 2024-04-03 21:16:05 +11:00
Christopher Kohlhoff c36d3ef338 Update copyright notices. 2024-03-05 07:51:17 +11:00
Christopher Kohlhoff 57a8c85f6d Remove deprecated handler allocation hooks. 2023-10-26 00:44:01 +11:00
Christopher Kohlhoff 944758cdaf Remove deprecated handler invocation hook. 2023-10-26 00:44:00 +11:00
Christopher Kohlhoff eae55c14d3 Remove deprecated execution functionality. 2023-10-26 00:43:05 +11:00
Christopher Kohlhoff a788ad8457 Fix links to experimental::promise reference page. 2023-04-05 21:43:14 +10:00
Christopher Kohlhoff adfeed2b5d Add any_completion_handler to the documentation. 2023-03-07 00:04:56 +11:00
Christopher Kohlhoff d341036043 Add protocol for AF_UNIX+SOCK_SEQPACKET. 2023-03-01 23:08:42 +11:00
Christopher Kohlhoff 0f5ed97183 Add bind_immediate_executor function and immediate_executor_binder adapter. 2023-03-01 23:05:44 +11:00
Christopher Kohlhoff e199980569 Add associated_immediate_executor associator. 2023-03-01 23:04:58 +11:00
Christopher Kohlhoff 35e93e4e90 Update copyright notices. 2023-03-01 23:03:03 +11:00
Christopher Kohlhoff 9e03478ba1 Add range-based experimental::make_parallel_group().
Added new overloads of experimental::make_parallel_group that may be used
to launch a dynamically-sized set of asynchronous operations, where all
operations are the same type. For example:

  using op_type = decltype(
      socket1.async_read_some(
        boost::asio::buffer(data1),
        boost::asio::deferred
      )
    );

  std::vector<op_type> ops;

  ops.push_back(
      socket1.async_read_some(
        boost::asio::buffer(data1),
        boost::asio::deferred
      )
    );

  ops.push_back(
      socket2.async_read_some(
        boost::asio::buffer(data2),
        boost::asio::deferred
      )
    );

  boost::asio::experimental::make_parallel_group(ops).async_wait(
      boost::asio::experimental::wait_for_all(),
      [](
          std::vector<std::size_t> completion_order,
          std::vector<boost::system::error_code> e,
          std::vector<std::size_t> n
        )
      {
        for (std::size_t i = 0; i < completion_order.size(); ++i)
        {
          std::size_t idx = completion_order[i];
          std::cout << "socket " << idx << " finished: ";
          std::cout << e[idx] << ", " << n[idx] << "\n";
        }
      }
    );

Thanks go to Klemens Morgenstern for supplying part of this implementation.
2022-11-03 00:48:45 +11:00
Christopher Kohlhoff 7b8d9b4f5f Fix link to experimental::co_composed. 2022-11-01 13:49:17 +11:00
Christopher Kohlhoff 1c0f3c36be Add experimental::co_composed.
The following example illustrates a simple asynchronous operation that
implements an echo protocol in terms of a coroutine:

  template <typename CompletionToken>
  auto async_echo(tcp::socket& socket,
      CompletionToken&& token)
  {
    return boost::asio::async_initiate<
      CompletionToken, void(boost::system::error_code)>(
        boost::asio::experimental::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), boost::asio::deferred);

                  co_await boost::asio::async_write(socket,
                      boost::asio::buffer(data, n), boost::asio::deferred);
                }
              }
              catch (const boost::system::system_error& e)
              {
                co_return {e.code()};
              }
            }, socket),
        token, std::ref(socket));
  }
2022-11-01 11:35:07 +11:00
Christopher Kohlhoff 64448e6a19 Add any_completion_handler<>.
The any_completion_handler<> template can be used to type-erase
completion handlers. A typical use case is to enable separate
compilation of asynchronous operation implementations. For example:

  // Header file:

  void async_sleep_impl(
      boost::asio::any_completion_handler<void(boost::system::error_code)> handler,
      boost::asio::any_io_executor ex, std::chrono::nanoseconds duration);

  template <typename CompletionToken>
  inline auto async_sleep(boost::asio::any_io_executor ex,
      std::chrono::nanoseconds duration, CompletionToken&& token)
  {
    return boost::asio::async_initiate<CompletionToken, void(boost::system::error_code)>(
        async_sleep_impl, token, std::move(ex), duration);
  }

  // Separately compiled source file:

  void async_sleep_impl(
      boost::asio::any_completion_handler<void(boost::system::error_code)> handler,
      boost::asio::any_io_executor ex, std::chrono::nanoseconds duration)
  {
    auto timer = std::make_shared<boost::asio::steady_timer>(ex, duration);
    timer->async_wait(boost::asio::consign(std::move(handler), timer));
  }
2022-11-01 11:00:16 +11:00
Christopher Kohlhoff ed722fb0a3 Add consign completion token adapter.
The consign completion token adapter can be used to attach additional
values to a completion handler. This is typically used to keep at least
one copy of an object, such as a smart pointer, alive until the
completion handler is called.

For example:

  auto timer1 = std::make_shared<boost::asio::steady_timer>(my_io_context);
  timer1->expires_after(std::chrono::seconds(1));
  timer1->async_wait(
      boost::asio::consign(
        [](boost::system::error_code ec)
        {
          // ...
        },
        timer1
      )
    );

  auto timer2 = std::make_shared<boost::asio::steady_timer>(my_io_context);
  timer2->expires_after(std::chrono::seconds(30));
  std::future<void> f =
    timer2->async_wait(
      boost::asio::consign(
        boost::asio::use_future,
        timer2
      )
    );
2022-11-01 11:00:15 +11:00
Christopher Kohlhoff 9c9b76f0ee Add any_completion_executor. 2022-11-01 11:00:15 +11:00
Christopher Kohlhoff 8603d5c39b Deprecate concepts, traits, functions and customisation points related to senders and receivers. 2022-11-01 11:00:15 +11:00
Christopher Kohlhoff 17e08c23fe Deprecate execution::execute member function.
Use execute as a member function.
2022-11-01 10:44:37 +11:00
Christopher Kohlhoff 32f8f72fcc Add use_promise and use_promise_t to the quick reference. 2022-08-01 09:25:54 +10:00
Christopher Kohlhoff 63972a52c0 Add completion_signature_of trait.
The completion_signature_of trait (and corresponding type alias
completion_signature_of_t) may be used to determine the completion
signature of an asynchronous operation. For example:

  auto d = my_timer.async_wait(asio::deferred);
  using sig = asio::completion_signature_of<decltype(d)>::type;
  // sig is void(error_code)

or with a handcrafted asynchronous operation:

  struct my_async_op
  {
    asio::ip::tcp::socket& socket_ = ...;

    template <typename Token>
    auto operator()(asio::const_buffer data, Token&& token)
    {
      return asio::async_write(socket_, data,
          std::forward<Token>(token));
    }
  };

  using sig =
    asio::completion_signature_of<
      my_async_op, asio::const_buffer>::type;
  // sig is void(error_code, size_t)
2022-06-30 01:08:13 +10:00
Christopher Kohlhoff 73efb7492c Add is_async_operation trait and async_operation concept.
The is_async_operation trait may be used to determine if a function
object, and optional arguments, may be called to initiate an
asynchronous operation. For example, when using asio::deferred

  auto d = my_timer.async_wait(asio::deferred);
  static_assert(asio::is_async_operation<decltype(d)>::value);

or with a handcrafted asynchronous operation:

  struct my_async_op
  {
    asio::ip::tcp::socket& socket_ = ...;

    template <typename Token>
    auto operator()(asio::const_buffer data, Token&& token)
    {
      return asio::async_write(socket_, data,
          std::forward<Token>(token));
    }
  };

  static_assert(
      asio::is_async_operation<
        my_async_op, asio::const_buffer>::value);
2022-06-30 01:08:13 +10:00
Christopher Kohlhoff 4c216747dc Move deferred to the asio namespace.
This is no longer an experimental facility. The names deferred and
deferred_t have been temporarily retained as deprecated entities under
the asio::experimental namespace, for backwards compatibility.
2022-06-30 01:08:13 +10:00
Christopher Kohlhoff 34f5627723 Move prepend to the asio namespace.
This is no longer an experimental facility. The names prepend and
prepend_t have been temporarily retained as deprecated entities under
the asio::experimental namespace, for backwards compatibility.
2022-06-30 00:43:16 +10:00
Christopher Kohlhoff f7356fbe90 Move append to the asio namespace.
This is no longer an experimental facility. The names append and
append_t have been temporarily retained as deprecated entities under
the asio::experimental namespace, for backwards compatibility.
2022-06-30 00:43:16 +10:00
Christopher Kohlhoff a312a46715 Move as_tuple to the asio namespace.
This is no longer an experimental facility. The names as_tuple and
as_tuple_t have been temporarily retained as deprecated entities under
the asio::experimental namespace, for backwards compatibility.
2022-06-30 00:43:16 +10:00
Christopher Kohlhoff d35b87ff27 Update documentation for dispatch, post, and defer. 2022-03-04 21:06:50 +11:00
Christopher Kohlhoff 2117b3ee7e Expose recycling_allocator as part of public interface. 2022-03-04 20:56:45 +11:00
Christopher Kohlhoff 7162c9675d Rework reference documentation in terms of completion tokens. 2022-03-02 22:13:21 +11:00
Christopher Kohlhoff 3cd04eee90 Add bind_allocator. 2022-03-02 21:57:41 +11:00
Christopher Kohlhoff ff58013a23 Update copyright notices. 2022-03-02 21:23:52 +11:00
Christopher Kohlhoff 495e6367af Add experimental support for channels.
This adds experimental::channel and experimental::concurrent_channel.
Channels may be used to send completions as messages. For example:

  // Create a channel with no buffer space.
  channel<void(error_code, size_t)> ch(ctx);

  // The call to try_send fails as there is no buffer
  // space and no waiting receive operations.
  bool ok = ch.try_send(asio::error::eof, 123);
  assert(!ok);

  // The async_send operation blocks until a receive
  // operation consumes the message.
  ch.async_send(asio::error::eof, 123,
      [](error_code ec)
      {
        // ...
      });

  // The async_receive consumes the message. Both the
  // async_send and async_receive operations complete
  // immediately.
  ch.async_receive(
      [](error_code ec, size_t n)
      {
        // ...
      });
2021-11-04 01:56:32 +11:00
Christopher Kohlhoff d8359719e1 Add support for registered buffers.
The mutable_registered_buffer and const_registered_buffer classes are
buffer sequence types that represented registered buffers. These buffers
are obtained by first performing a buffer registration:

  auto my_registration =
    asio::register_buffers(
        my_execution_context,
        my_buffer_sequence);

The registration object must be maintained for as long as the buffer
registration is required. The supplied buffer sequence represents the
memory location or locations that will be registered, and the caller
must ensure they remain valid for as long as they are registered. The
registration is automatically removed when the registration object is
destroyed. There can be at most one active registration per execution
context.

The registration object is a container of registered buffers. Buffers
may be obtained from it by iterating over the container, or via direct
index access:

  asio::mutable_registered_buffer my_buffer
    = my_registration[i];

The registered buffers may then be passed directly to operations:

  asio::async_read(my_socket, my_buffer,
      [](error_code ec, size_t n)
      {
        // ...
      });

Buffer registration supports the io_uring backend when used with read
and write operations on descriptors, files, pipes, and sockets.
2021-10-29 20:54:56 +11:00