-
Notifications
You must be signed in to change notification settings - Fork 1
Description
This code is incorrect:
boost::asio::async_completion<CompletionToken, write_signature> c(token);
do_write(std::move(c.completion_handler));
The problem is that do_write
receives the handler as a std::function
, which type-erases the handler. Later on, you call boost::asio::post
with this object. Since the function object is typed-erased, it loses the associated allocator and more importantly the associated executor. The consequence is that when a user writes:
auto const bytes_transferred =
utp_sock.async_write_some(
buffers,
boost::asio::bind_executor(strand_, my_handler));
The wrapper returned by bind_executor
loses its type information when it is stored in a function object. Then later on when you call post
, it doesn't go through the strand.
This is going to sound painful, but if you want your library to work nicely with Networking TS / Asio (and I think you have really nice library here, so you should want this) then you are going to have to do the following:
- Remove all use of
std::function
(and never use it again) - Move everything in the .cpp files into header files (this library must be header-only to work right)
- Rewrite your asynchronous operations (connect, read some, write some) as composed operations
These tutorials should help:
https://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/using_io/writing_composed_operations.html
https://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/using_io/example_detect_ssl.html
You might also consider studying the implementation of asio and beast. I can help with that by offering pointers and answering questions.