user1545583
user1545583

Reputation: 69

resetting boost::deadline_timer in handler causing crash

Below is sample code of Timer I am using in my server. It is a multithreaded process that process loads of data. Once timer triggers it does some operation on processed data and reset itself for new time

class MyTimer
{
    public:
        MyTimer(boost::asio::io_service& ios):strand_(ios)
        {
            for (int i = 0; i < 10; i++)
            {
                std::auto_ptr<boost::thread> thread(
                        new boost::thread(boost::bind(&boost::asio::io_service::run,
                                          &ios_)));
                thread_pool_.push_back(thread.get());
                thread.release();
            }
            boost::posix_time::seconds expTime(10);
            eodTimer_.reset(new boost::asio::deadline_timer(ios));
            eodTimer_->expires_from_now(expTime);
            eodTimer_->async_wait(boost::bind(&MyTimer::onTimer, this));
        };

         ~MyTimer()
         {
              ThreadPool::iterator it(thread_pool_.begin());
              for (; it != thread_pool_.end(); ++it)
              {
                   (*it)->join();
                   delete *it;
               }
         }
        void onTimer()
        {
            //do some stuff...
            // reset timer
            boost::posix_time::seconds expTime(10);
            eodTimer_->expires_from_now(expTime);
            eodTimer_->async_wait(boost::bind(&MyTimer::onTimer, this));
        }

    private:
        boost::asio::io_service ios;
        boost::asio::strand strand_;
        boost::scoped_ptr<boost::asio::deadline_timer> eodTimer_;
};

So far I do not see any issue with this code. But after running from some hours my Server crashes. Stack trace points me to ::onTimer callback handler.

#0  0x0a446c06 in boost::asio::detail::timer_queue<boost::asio::time_traits<boost::posix_time::ptime> >::cancel_timer (this=0xe3be0bc,
    timer_token=0xe9877ec) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/timer_queue.hpp:141
#1  0x0a445791 in boost::asio::detail::epoll_reactor<false>::cancel_timer<boost::asio::time_traits<boost::posix_time::ptime> > (this=0xe49f498,
        timer_queue=..., token=0xe9877ec) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/epoll_reactor.hpp:424
#2  0x0a444197 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail::               epoll_reactor<false> >::cancel (this=0xe3be0a8, impl=..., ec=...) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:104    #3  0x0a443f31 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail::               epoll_reactor<false> >::expires_at (this=0xe3be0a8, impl=..., expiry_time=..., ec=...)
            at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:120
#4  0x0a441e92 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail::               epoll_reactor<false> >::expires_from_now (this=0xe3be0a8, impl=..., expiry_time=..., ec=...)
                at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:137
#5  0x0a43f895 in boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> >::                expires_from_now (
                    this=0xe49f438, impl=..., expiry_time=..., ec=...) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/deadline_timer_service.hpp: 144
#6  0x0a451d64 in boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::       deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >::expires_from_now (this=0xe9877e8, expiry_time=...)
                        at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/basic_deadline_timer.hpp:297
#7  0x0a44e941 in fxpay::AggregatorRouter::Impl::MyTimer::onTimer (this=0xe987e48) at MyTimer.cpp:183

Is there something wrong the way I am using boost::dead_line timer? (I am using 1.39 boost version)

Upvotes: 0

Views: 854

Answers (1)

sehe
sehe

Reputation: 393447

You're running 10 threads and there is no synchronization of access to eodTimer.

The deadline_timer object is not threadsafe, so you get Undefined Behaviour because of the data race.

Did you mean to run the timer on a strand?

Upvotes: 1

Related Questions