1

According to boost documentation: For each call to async_wait(), the supplied handler will be called exactly once. The handler will be called when: - The timer has expired. - The timer was cancelled, in which case the handler is passed the error code boost::asio::error::operation_aborted.

for a similar code:

std::unique_ptr<timer> periodSendTimer_;

ContentQueue::ContentQueue(...timer....): periodSendTimer_(timer){}

ContentQueue::~ContentQueue()
{
    periodSendTimer_->cancel();
}

void ContentQueue::startSendLoop(const boost::system::error_code& error)
{
     if (not error)
        {
            periodSendTimer_->expires_from_now(boost::posix_time::seconds(1));
            periodSendTimer_->async_wait(boost::bind (&ContentQueue::startSendLoop, this, boost::asio::placeholders::error));
        }
        else if(error == boost::asio::error::operation_aborted)
        {.....}
          else
           {....}
}

My problem is that very very rarely it happens that Destructor is called but in the same time(until timer will be canceled) timer expires(from expires_from_now) and for handler startSendLoop is NOT passed as expected boost::asio::error::operation_aborted.

Any feedback/solution?

sehe
  • 374,641
  • 47
  • 450
  • 633
AlexM
  • 111
  • 4
  • Use `std::weak_ptr`. – Abyx Jun 13 '17 at 16:19
  • There's a race condition in your code. When invoke the destructor, the timer could fire before you get a chance to cancel it or it could have already fired. How you fix it depends on details about your implementation that we don't know. (For example, can the timer always be handled by a different thread so the destructor can just wait for it?) – David Schwartz Nov 12 '18 at 18:45

0 Answers0