Am Mo., 9. Sept. 2019 um 02:31 Uhr schrieb Gavin Lambert via Boost-users <boost-users@lists.boost.org>:
On 4/09/2019 02:21, Stephan Menzel wrote:
> my experiments with custom composed operations in asio have led me to
> another question regarding the use of such methods.
> What do I do in order to have multiple handlers in flight, e.g. for a timer?

Not sure if this helps, but the way that I've done something similar in
the past is simply to have different overloads of operator() for each
unique operation signature.

(Note that my example is for a sequential operation, not a parallel one,
but in principle you should be able to do something similar.)

For example:

   operator()()
     -> kicks off first async_wait
   operator()(error_code)
     -> handles result of async_wait and kicks off async_read
   operator()(error_code, size_t)
     -> handles result of async_read and kicks off another async_wait

This doesn't actually use the coroutine mechanism since the actions are
split between multiple methods rather than being multiplexed, but I
think it still read pretty clearly this way.


Ah, OK. I had tried this before but failed as I thought it is mandatory to have all parameters except Self defaulted. It says so in the example. Since I did this, the handler types collided.

I have now implemented this approach in a socks connect function I had trouble with (see my other post) and it works fine without the coroutine:

https://github.com/MrMoose/moose_tools/blob/master/SOCKS4.hpp

Thanks! It was a great idea to try that again.

If you're switching between two operations that have the same signature
(eg. async_read and async_write) then you'll need additional state in
the handler object to determine which one was in flight; if you're
trying to run them in parallel then you'll need to bind an extra handler
argument to disambiguate which one completed first.

The coroutine approach sure looked nicer but having a little state machine for small composed ops like this doesn't hurt. As iong as it doesn't get much more complex we're fine.

About your other message:
Yes, when implementing the timeout the moving of the handler turned out to be the main reason the idea of forking gave me trouble. I was not aware shared ownership of the handler is an option though.
My impl of the timed_connect works now but isn't very nice by and standard. Also, I'll be needing to include the timeout into the socks_connect as well so I will experiment with shared ownership of the handler and see where that takes me. Thanks!

Cheers,
Stephan