-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test::stream doesn't keep an executor work guard? #1418
Comments
This looks like a bug! |
Are we sure this isn't a problem with |
Not really sure, no. Since I was not sure it's a real issue I have not explored it in too much detail yet. I found the issue testing an implementation of a real protocol over Websockets. Using this
to "test" https://www.boost.org/doc/libs/1_69_0/libs/beast/example/echo-op/echo_op.cpp I get
Which looks fine... but it's not exactly the same. |
The behavior of Beast is correct - asynchronous operations cannot maintain I/O work guard for you, so if your handler context is different than your I/O context, you need to maintain a work guard yourself. (If the same context is used for both, you can safely omit the work guard). |
Isn't https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/asynchronous_operations.html
saying asynchronous operations will maintain I/O work guard for me? |
Yes, but your asynchronous operation as written does not maintain a guard across multiple calls to Beast's asynchronous operations. In your first code example, there is an implicit composed asynchronous operation, the |
@reddwarf69 You have to keep in mind what completion, in the context of async operations, means:
So work guards have to be maintained until completion, and completion means |
I see now that while simplifying I forgot about the AsyncStream executor work guard, is this the one you are talking about? Notice that the problem I'm seeing is related to the handler executor work guard. To play with something more familiar. Let's look at this code, a modified version of echo_op:
(I made the flat_buffer global to keep it simple)
My asynchronous operation certainly doesn't keep a work guard for the handler associated executor. But neither does the echo_op example from Beast. Are you arguing the echo_op example should keep a work guard for the handler executor because between https://github.com/boostorg/beast/blob/boost-1.69.0/example/echo-op/echo_op.cpp#L212 and https://github.com/boostorg/beast/blob/boost-1.69.0/example/echo-op/echo_op.cpp#L219 there is a moment where there is no guard? |
It does look like a guard is missing from echo-op! |
FWIW I was asking myself why the echo_op is as it is and in the boost-users mailing list Damian managed to convince me the second guard is not needed (https://lists.boost.org/boost-users/2018/11/89019.php). Basically, I would expect this in my latest example:
So, without async_connect() explicitly having a handler executor work guard, the handler executor work count is never zero. Also in the brand new composed operation example from asio only one work guard is explicitly created -> https://github.com/boostorg/asio/blob/develop/example/cpp11/operations/composed_5.cpp#L84 |
The issue (if there is an issue) would be in
outputs
I guess there is a need for a second work guard here -> https://github.com/boostorg/beast/blob/develop/include/boost/beast/_experimental/test/impl/stream.hpp#L459 ? |
So this is likely to be a misunderstanding on my part. But just in case I have found an actual bug...
When running this code with Boost 1.69
I get this output:
It's my understanding that after calling
client_handler_ioc.poll()
client_stream.async_read(buffer, boost::asio::bind_executor(client_handler_ioc, <completion_handler>));
has been called. I would have expected that call to async_read to have created a "work" for the client_handler_ioc executor, and so it should have not "stopped".The text was updated successfully, but these errors were encountered: