[Asio] Combining use_future with strands

Hi, Is there a way to combine the special use_future completion token with a strand? Something with the meaning of: - the asynchronous operation should pass the result to the future it returns, and - the internal operations of it (if any) should run in a strand Code snippet: asio::io_context io_context; asio::io_context::strand strand(io_context); std::future<void> f = async_my_operation(io_context, <params>, asio::use_future); //________________________________________How to add the strand here ^^^ ? The code area where I would like to apply this is in this test program: https://github.com/sorf/cpp-dev-new/blob/abf9d831a0b82fb81751eee6cfa498d3b98... The self contained program and its output is here: https://wandbox.org/permlink/pF5Hbm6jqPOmEKbO As a background, the test program I wrote is based on these Boost.Asio examples: - for strand usage (i.e. bind_executor): https://github.com/boostorg/asio/blob/develop/example/cpp03/tutorial/timer5/... - for composed operations: https://github.com/boostorg/asio/blob/develop/example/cpp11/operations/compo... and implements a composed operation that runs multiple internal operations in parallel and in series. Similar to the constructor of a socket or a timer object, the operation receives as a parameter an io_context; it doesn't offer an overload that receives a strand object directly. The operation is then tested with callback completion, callback completion in a strand, future and future + strand (where the test fails). Thank you, Sorin

I've been discussing a very similar thing with Vinnie Falco, here: https://github.com/boostorg/beast/issues/1366 On Mon, 17 Dec 2018 at 13:39, Sorin Fetche via Boost-users < boost-users@lists.boost.org> wrote:
Hi,
Is there a way to combine the special use_future completion token with a strand? Something with the meaning of: - the asynchronous operation should pass the result to the future it returns, and - the internal operations of it (if any) should run in a strand
Code snippet: asio::io_context io_context; asio::io_context::strand strand(io_context); std::future<void> f = async_my_operation(io_context, <params>, asio::use_future); //________________________________________How to add the strand here ^^^ ?
The code area where I would like to apply this is in this test program:
https://github.com/sorf/cpp-dev-new/blob/abf9d831a0b82fb81751eee6cfa498d3b98...
The self contained program and its output is here: https://wandbox.org/permlink/pF5Hbm6jqPOmEKbO
As a background, the test program I wrote is based on these Boost.Asio examples: - for strand usage (i.e. bind_executor): https://github.com/boostorg/asio/blob/develop/example/cpp03/tutorial/timer5/...
- for composed operations: https://github.com/boostorg/asio/blob/develop/example/cpp11/operations/compo...
and implements a composed operation that runs multiple internal operations in parallel and in series. Similar to the constructor of a socket or a timer object, the operation receives as a parameter an io_context; it doesn't offer an overload that receives a strand object directly.
The operation is then tested with callback completion, callback completion in a strand, future and future + strand (where the test fails).
Thank you, Sorin
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Richard Hodges hodges.r@gmail.com office: +442032898513 home: +376841522 mobile: +376380212 (this will be *expensive* outside Andorra!) skype: madmongo facebook: hodges.r

On Sun, Dec 16, 2018, 11:52 PM Richard Hodges wrote:
I've been discussing a very similar thing with Vinnie Falco, here: https://github.com/boostorg/beast/issues/1366
On Mon, 17 Dec 2018 at 13:39, Sorin Fetche via Boost-users < boost-users@lists.boost.org> wrote:
Is there a way to combine the special use_future completion token with a strand?
If this is not currently possible, shouldn't it be an issue (bug/missing feature) of Asio?
Initially, when writing the code, I was kind of expecting that asio::bind_executor works with asio::use_future, but the compiler disagreed with me. So, I think I'll raise an issue on this against the Boost.Asio library. Best regards, Sorin

Hi Sorin, This is a known issue in ASIO - `asio::use_future` has an associated executor (which is used to redirect exceptions), but the problem is that the implementation doesn't use the `associated_executor` type trait to wrap an executor associated with the I/O object that is used. Instead, it uses the intrusive executor hook, which "overrides" the executor associated with the I/O object. Note that if `bind_executor` were to work with it, it would cause the exception redirection to break. As a sidenote: asio::io_context::strand is deprecated and should not be used in projects that use ASIO 1.66+. You should use `asio::strand<io_context::executor_type>` instead. On Mon, Dec 17, 2018 at 6:23 PM Sorin Fetche via Boost-users < boost-users@lists.boost.org> wrote:
On Sun, Dec 16, 2018, 11:52 PM Richard Hodges wrote:
I've been discussing a very similar thing with Vinnie Falco, here: https://github.com/boostorg/beast/issues/1366
On Mon, 17 Dec 2018 at 13:39, Sorin Fetche via Boost-users < boost-users@lists.boost.org> wrote:
Is there a way to combine the special use_future completion token with a strand?
If this is not currently possible, shouldn't it be an issue (bug/missing feature) of Asio?
Initially, when writing the code, I was kind of expecting that asio::bind_executor works with asio::use_future, but the compiler disagreed with me. So, I think I'll raise an issue on this against the Boost.Asio library.
Best regards, Sorin
_______________________________________________
Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

On Mon, Dec 17, 2018 at 10:26 AM Damian Jarek <damian.jarek93@gmail.com> wrote:
Hi Sorin, This is a known issue in ASIO - `asio::use_future` has an associated executor (which is used to redirect exceptions), but the problem is that the implementation doesn't use the `associated_executor` type trait to wrap an executor associated with the I/O object that is used. Instead, it uses the intrusive executor hook, which "overrides" the executor associated with the I/O object. Note that if `bind_executor` were to work with it, it would cause the exception redirection to break.
Hi Damian, Do you know if there is any issue / ticket raised for this so I can track it over time? I didn't find anything related to use_future neither in the GitHub issues nor the old Trac. Based on your description of the problem and some cursory debugging in use_future, I would expect this to be an implementation issue that could be addressed at some point.
As a sidenote: asio::io_context::strand is deprecated and should not be used in projects that use ASIO 1.66+. You should use `asio::strand<io_context::executor_type>` instead.
I changed this plus added an executor parameter to the composed operation here: https://github.com/sorf/cpp-dev-new/commit/52cebd112a4427bd9b7f3d1ef1e9c391a... Self contained program here: https://wandbox.org/permlink/RSghEe81IQRxpZfh And indeed, it didn't do any help when combining use_future + strand. At least it showcases two ways of passing the strand when using the completion callback and the composed operation has an explicit executor parameter. Thanks, Sorin

On 18/12/2018 07:26, Damian Jarek wrote:
As a sidenote: asio::io_context::strand is deprecated and should not be used in projects that use ASIO 1.66+. You should use `asio::strand<io_context::executor_type>` instead.
That seems like a poor tradeoff of names. I hope the former will never be removed and will just typedef to the latter.

On Tue, Dec 18, 2018 at 2:46 PM Gavin Lambert via Boost-users <boost-users@lists.boost.org> wrote:
That seems like a poor tradeoff of names. I hope the former will never be removed and will just typedef to the latter.
Do you think that when Networking TS is merged to the standard in 2026, that it should also have both `std::net::strand` and `std::net::io_context::strand`? Regards

On 19/12/2018 12:37, Vinnie Falco wrote:
On Tue, Dec 18, 2018 at 2:46 PM Gavin Lambert wrote:
That seems like a poor tradeoff of names. I hope the former will never be removed and will just typedef to the latter.
Do you think that when Networking TS is merged to the standard in 2026, that it should also have both `std::net::strand` and `std::net::io_context::strand`?
That's a false equivalence. If the question is whether these should both exist: std::net::strand<Executor> std::net::io_context::strand Where the latter is a typedef/using to std::net::strand<std::net::io_context::executor_type> ... Then absolutely, yes, both of these should exist. Convenience typedefs are not redundant, especially where they both save typing and are logically easy to find. Now, if std::net::strand wasn't templated on the executor type, then that might change the answer.
participants (5)
-
Damian Jarek
-
Gavin Lambert
-
Richard Hodges
-
Sorin Fetche
-
Vinnie Falco