
On 25 July 2018 at 19:12, Vinnie Falco via Boost-users <boost-users@lists.boost.org> wrote:
On Wed, Jul 25, 2018 at 7:25 AM, Cristian Morales Vega via Boost-users <boost-users@lists.boost.org> wrote:
The following simplified sample shows the problem:
First of all thank you for posting a minimal, complete, and verifiable example.
It looks like your implementation of async_method() is missing one or two executor_work_guard objects:
Per N4734[1] 13.2.7.10 Outstanding Work [async.reqmts.async.work]
1. Until the asynchronous operation has completed, the asynchronous operation shall maintain:
(1.1) — an object work1 of type executor_work_guard, initialized as work1(ex1), and where work1.owns_work() == true; and
(1.2) — an object work2 of type executor_work_guard, initialized as work2(ex2), and where work2.owns_work() == true.
I don't think you can get away with just calling `post` from `async_method` you need to write a "real" composed operation class with all of the bells and whistles including forwarding of the associated executor and associated allocator. In this class you can store the two required executor_work_guard objects as data members.
A tutorial for writing composed operations may be found here:
Thanks
13.2.7.1 says The life cycle of an asynchronous operation is comprised of the following events and phases: (2.1) — Event 1: The asynchronous operation is started by a call to the initiating function. (2.2) — Phase 1: The asynchronous operation is now outstanding. (2.3) — Event 2: The externally observable side effects of the asynchronous operation, if any, are fully established. The completion handler is submitted to an executor. (2.4) — Phase 2: The asynchronous operation is now completed. By this definition of "completed" shouldn't my sample code be fine? This is not supposed to be a composed operation. In any case I was looking at basic_socket::async_connect() and I noticed I was using async_completion differently. After changing "boost::asio::async_completion<ConnectHandler, void(const boost::system::error_code &)>" for "boost::asio::async_completion<ConnectHandler, void(boost::system::error_code)>" (error_code by value, not const reference) my sample code has started working correctly. I'm not sure I *really* understand what was going on (or if this couldn't have been detected at compile time). But... it kind of makes sense.