Boost logo

Boost :

Subject: Re: [boost] Should pass boost::asio::io_service by raw pointer or smart pointer?
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2018-12-26 03:12:42

On Tue, Dec 25, 2018 at 4:54 AM Antony Polukhin via Boost
<boost_at_[hidden]> wrote:
> Hmmm... just double checking that my knowledge is up to date: there's no
> way to create a timer, async wait for it and pass the ownership to the
> callback. In other words, code like the following can not be improved in
> C++14:

The version of C++ has nothing to do with what is possible or how the
asynchronous ownership model works. I/O objects need a stable address.
After an asynchronous operation completes, it is likely that the
operation will be repeated in the future. For example, you will likely
read from a socket again. Therefore, your "operation" for delaying the
execution of a single function object might look like this:

    class delayed_runner
        net::steady_timer tm_;

        using clock_type = std::steady_clock;
        template <class NullaryFunction>
        NET_INITFN_RESULT_TYPE(NullaryFunction, void(void))
        async_run_after (clock_type::duration expiry_time, NullaryFunction&&);

        template <class NullaryFunction>
        NET_INITFN_RESULT_TYPE(NullaryFunction, void(void))
        async_run_at (clock_type::time_point expiry_time, NullaryFunction&&);

        void cancel();

The caller is responsible for ensuring this object is not destroyed
while there is an outstanding operation. Similar to how a socket is
treated, a `delayed_runner` would be a data member of some "session"
object which is itself managed by `shared_ptr`. Completion handlers
use a "handler owns I/O object" shared ownership model, so the
function object contains a bound copy of the shared pointer, ensuring
that the lifetime of the I/O object extends until the function object
is invoked or destroyed.


Boost list run by bdawes at, gregod at, cpdaniel at, john at