|
Boost Users : |
From: Gavin Lambert (boost_at_[hidden])
Date: 2019-09-10 23:54:45
On 10/09/2019 17:10, Stephan Menzel wrote:
> I'm in the process of creating more such composed ops for ever recurring
> use cases and perhaps I find a way to tie this lambdas lifetime to the
> whole operation. As it happens, my gut felling tells me there are cases
> when the timer lambda will dangle around and potentially crash, perhaps
> when the op is used and the io_service being destroyed and not polled
> before destruction. I couldn't verify this in the unit test yet but
> there's often cases like this that go overlooked.
Yes, you may have a lifetime problem if the timer has not yet expired
when m_socket is destroyed.
Since the owner of the timer also assumes a shorter lifetime than
m_socket (due to capturing it by reference), the timer should get
cancelled before m_socket is destroyed (unless you have a different
bug). The handler might not have been called yet, but on the
cancellation path you immediately return anyway, so it shouldn't be an
issue. (Though there might be a corner case if it expires just as you
destroy things.)
If you do dispose of the io_service before all handlers are called, then
they will not be called, but their destructors will still fire.
Occasionally this means you need to be careful about the order of
destruction when the destructors aren't trivial, but otherwise this
behaves sensibly.
But yes, async can make it quite hairy to verify that lifetimes occur
the right way around -- which is one of the reasons why you see
shared_ptr used a lot in async code.
When you're trying to provoke these sorts of issues in unit tests, using
run_one() can be very helpful.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net