Search code examples
c++boostpthreadsboost-asiodeadline-timer

Error using boost::asio::deadline_timer while execution


I am trying to implement a basic deadline timer using this code:

          class Example
          {
              Example(boost::asio::io_service& ios, config& cfg)
                        : ios_(ios), cfg_(cfg), tcp_client_(ios) {
    
                state = new State();
                boost::asio::deadline_timer t(ios, boost::posix_time::seconds(5));
                t.async_wait(boost::bind(&bse_dummy_exchange::start_heartbeats,this,boost::asio::placeholders::error,boost::ref(t)));
              }
              ~Example() = default;
              void start_heartbeats(const boost::system::error_code& e,boost::asio::deadline_timer& t)
              {
                  std::cout << "Hello, world!\n";
                  t.expires_from_now(boost::posix_time::seconds(5));
     t.async_wait(boost::bind(&bse_dummy_exchange::start_heartbeats,this,boost::asio::placeholders::error,boost::ref(t)));
              }
          }

Compilation goes fine, but while executing I get this error message which I don't understand, can someone please help me with it:

    Hello, world!
    bse_dummy_exchange: ../nptl/pthread_mutex_lock.c:425: 
    __pthread_mutex_lock_full: Assertion `INTERNAL_SYSCALL_ERRNO (e, __err) 
    != ESRCH || !robust' failed.
    Aborted (core dumped)

Solution

  • You don't show the mutex - so we can't answer.

    That said, about everything is going wrong with respect to async that can go wrong:

    (I'm for the sake of understanding your code assuming that Example was actually named use_dummy_exchange)

    At the very least, the timer needs to have lifetime extending beyond the lifetime of the async_wait.

    Minimal Fixed Version

    Of course, not fixing anything related to the mutex error - that was not included:

    Live On Coliru

    #include <boost/asio.hpp>
    #include <iostream>
    struct config { };
    
    struct TcpClient {
        TcpClient(boost::asio::io_service& ios) : ios_(ios){}
      private:
        boost::asio::io_service& ios_;
    };
    
    struct Example {
        struct State {};
        std::unique_ptr<State> state;
    
        Example(boost::asio::io_service& ios, config& cfg)
            : state(std::unique_ptr<State>()),
              ios_(ios),
              cfg_(cfg),
              tcp_client_(ios)
        {
            heartbeats();
        }
    
        void heartbeats(const boost::system::error_code& e = {}) {
            std::cout << "Hello, world!" << std::endl;
            if (!e) {
                t.expires_from_now(boost::posix_time::seconds(5));
                t.async_wait([this](auto ec) { heartbeats(ec); });
            }
        }
    
      private:
        boost::asio::io_service& ios_;
        config cfg_;
        TcpClient tcp_client_;
        boost::asio::deadline_timer t{ios_};
    };
    
    int main() {
        boost::asio::io_service ios;
        config cfg;
        Example ex(ios, cfg);
    
        ios.run_for(std::chrono::seconds(12));
    }
    

    Prints

    Hello, world!
    Hello, world!
    Hello, world!
    

    It has no memory leak, and runs clean under UBSan/ASan