Ov3r1oad
Ov3r1oad

Reputation: 1125

Thread safe work with boost::asio timers

I have a question about boost asio timers and safe-thread work with them. Let's say, i have the following class:

CTest.h:

class CTest
{
    boost::asio::io_service io;
    boost::asio::deadline_timer timer;

    void Check();
    CTest ();

    ~CTest ();
};

And CTest.cpp:

CTest::CTest():
timer (io, boost::posix_time::seconds(0))
{
    timer.async_wait(boost::bind(&CTest::Check, this));
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
}

void CTest::Check()
{
    //some work

    m_timer.expires_from_now(boost::posix_time::seconds(10));
    m_timer.async_wait(boost::bind(&CTest::Check, this));

}

CTest::~CTest()
{
     io.stop();
}

So, the question is how to finish Check thread safe? I mean, this Check function can be called after destructor, and we have a crash.

Upvotes: 1

Views: 968

Answers (2)

Galimov Albert
Galimov Albert

Reputation: 7357

Your destructor should stop all timers, so they will not be called after object is destroyed: m_timer.cancel(). Also, if you want to prevent simultaneous methods calls on same object, wrap your boost::bind with boost::asio::strand::wrap. Check out asio documentation for examples.

Upvotes: 1

janm
janm

Reputation: 18339

Using io_service::stop() is very rarely what you want to do.

A few points:

  • Keep the thread object around, and call thread.join() to make sure it is complete.
  • Don't call io.stop(), call m_timer.cancel() then m_thread.join() to clean up.
  • Consider using shared_ptr and weak_ptr to manage object lifetime more cleanly (ie: bind a weak_ptr instance into your async_wait callback rather than a bare this. In the callback function, convert the weak_ptr to a shared_ptr and if that is valid then call the method.
  • m_timer wil be used from multiple threads, you need to manage access using a mutex.

Just a few points. Not going to rewrite your code for you.

Upvotes: 2

Related Questions