Boost logo

Boost Users :

Subject: [Boost-users] [asio] deadline_timer callback is not called
From: Daniele Barzotti (daniele.barzotti_at_[hidden])
Date: 2009-10-14 09:44:15


Hi,

I've yet posted a question about this topic but I not solve, so I try to
ask again.

PS: I used the same solution (in conjunction with asio::serial_port) in
another project and, there, it works!

I'm working on a library and I have only one static io_service and
io_service::work like in the following code:

---------------------- START CODE ------------------------

typedef boost::shared_ptr<boost::asio::io_service::work> io_work_ptr;

// Main io_service
static boost::asio::io_service io_service;
static boost::scoped_ptr<boost::thread> io_service_thread;
static io_work_ptr p_work;
static bool thread_started;

void io_worker_thread(void)
{
  #if(WIN32 && _WIN32_DCOM)
    struct com_init {
      com_init() { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); }
      ~com_init() { CoUninitialize(); }
    } initializer_object;
  #endif

  io_service.run();
};

bool CreateMainThread()
{
  if (!thread_started) {
    try {
      // create the work object on the heap:
      // [Reference counting]
      // This object is a simple pointer because
      // it is assigned to each created objects
      // These objects store it in a shared_ptr so,
      // when the last object is destroyed
      // The io_service::work is destroyed as well
      p_work.reset( new boost::asio::io_service::work(io_service) );

      // Instead of start the worker thread directly by
      // passing the io_service object,
      // I call the io_worker_thread function where
      // I can do some initialization tasks like
      // calling CoInitializeEx for COM
      io_service_thread.reset(new boost::thread(io_worker_thread));

      thread_started = !thread_started;
      return true;

    } catch (boost::thread_resource_error e) {
      // Failed to create the new thread
      return false;
    }
  }
  else
    return true;
}

/*!
 * \brief Factory function for AudioPlayer objects creation
 */
EXTERN_C EUROAUDIOLIB_API AudioPlayerHndl CALL CreateAudioPlayer()
{
  if (!CreateMainThread()) return NULL;
  // create the new object
  AudioPlayer* pAudioPlayer = new AudioPlayer;
  pAudioPlayer->io_worker_ptr = p_work;
  return pAudioPlayer;
};

---------------------- END CODE ------------------------

In the above code pAudioPlayer->io_worker_ptr is declared as:

io_work_ptr p_work;

In a class I have to use the timer, so I initialize it with the global
io_service object:

---------------------- START CODE ------------------------

boost::asio::deadline_timer rx_timer_;

WaveStream::WaveStream() : rx_timer_(io_service)
{
};

void WaveStream::ProcessRTPPacket()
{
  // RTP Packet received

  ......

  //Start a new timer or renew it
  rx_timer_.expires_from_now( boost::posix_time::milliseconds( 1000 ) );

  io_service.reset();

  // We managed to cancel the timer. Start new asynchronous wait.
  rx_timer_.async_wait(
     boost::bind(&WaveStream::handle_timeout, this, _1)
  );

  ....
}

void WaveStream::handle_timeout(const boost::system::error_code& error)
{
  std::cout << "BOOST TIMER RAISED!!" << endl;

  // A Timeout is raised: a stream is end
  if (!error) {...}
};
---------------------- END CODE ------------------------

But the callbak is never called!!
Since ProcessRTPPacket is called frequently, I try also to move the
timer on another point just for test with the same effect!

Where could be the mistake?

Thanks in advance!
Daniele.


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