When registering a signal, it is now possible to pass flags that specify
the behaviour associated with the signal. These flags are specified as
an enum type in a new class, signal_set_base, and are passed to the
underlying sigaction() call. For example:
asio::signal_set sigs(my_io_context);
sigs.add(SIGINT, asio::signal_set::flags::restart);
Specifying flags other than flags::dont_care will fail unless
sigaction() is supported by the target operating system. Since signal
registration is global, conflicting flags (multiple registrations that
pass differing flags other than flags::dont_care) will also result in
an error.
The _buf literal suffix, defined in namespace asio::buffer_literals, may
be used to create const_buffer objects from string, binary integer, and
hexadecimal integer literals. These buffer literals may be arbitrarily
long. For example:
using namespace asio::buffer_literals;
asio::const_buffer b1 = "hello"_buf;
asio::const_buffer b2 = 0xdeadbeef_buf;
asio::const_buffer b3 = 0x01234567'89abcdef'01234567'89abcdef_buf;
asio::const_buffer b4 = 0b1010101011001100_buf;
The memory associated with a buffer literal is valid for the lifetime of
the program. This means that the buffer can be safely used with
asynchronous operations:
async_write(my_socket, "hello"_buf, my_handler);
This means that use_coro does not return a coro object, just like
use_awaitable does, i.e. it's an overhead that buys us type erasure.
Allocators can now be set for coro by including allocator_arg in the
coro signature.
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
)
);
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.
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.
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.
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.
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)
{
// ...
});
* Added overload so member functions can provide an explicit executor.
* Added co_spawn for coro tasks.
* Added reference and overview documentation.
* Adopted awaitable cancellation model.
* Refactored implementation.