-
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.