vicg
vicg

Reputation: 1368

In boost::asio is it possible to have one deadline_timer with multiple execution times?

So I was experimenting with the deadline_timer class and wrote the code below to see if I could have on deadline_timer with multiple async_wait operations that would execute at different times.

Below I create a deadline timer in the main function all the way at the bottom and initially set it to expire after 3 seconds. Then I call an async_wait operation and pass the first print function as the handler. I then use the expires_from_now operation to set the time of expiration for what I intended to only affect the second async_wait call which has print2 as a handler. The output from running this is below the code.

This is test1.cpp

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <time.h>
#include <sys/time.h>

double get_wall_time(){
    struct timeval time;
    if (gettimeofday(&time,NULL)){
        //  Handle error
        return 0;
    }
    return (double)time.tv_sec + (double)time.tv_usec * .000001;

}
void print(double start, const boost::system::error_code& /*e*/)
{
  std::cout << "Hello, world!" << std::endl;
  std::cout << get_wall_time() - start << std::endl;


}
void print2(double start, const boost::system::error_code& /*e*/)
{
  std::cout << "SECOND Hello, world!" << std::endl;
  std::cout << get_wall_time() - start << std::endl;


}

int main(int argc, char* argv[])
{
  boost::asio::io_service io;
  boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3));
  auto start = get_wall_time();
  timer.async_wait(boost::bind(print, start, boost::asio::placeholders::error));
  timer.expires_from_now(boost::posix_time::seconds(20));
  timer.async_wait(boost::bind(print2, start, boost::asio::placeholders::error));

  io.run();
  return 0;
}

Here is the output

Hello, world!
0.000774145
SECOND Hello, world!
20.0085

This is the output after commenting out the second async_wait with the expiration modification.

Hello, world!
3.00079

As you can see the first handler executes instantly when I intended for it to execute after 3 seconds. The second handler correctly executes after 20 seconds. Is there any way I could get the behavior I intended with a deadline_timer without having to create a bunch of them?

Upvotes: 0

Views: 2149

Answers (1)

Richard Hodges
Richard Hodges

Reputation: 69902

A timer must have only one outstanding async_wait at a time. IIRC, issuing another implicitly cancels the first one (which will fire it's handler with an error code) as if you called cancel() followed by async_wait().

If you want to respond to 2 timer events, you have 2 choices. Either have 2 timers, or set the timeout and issue the second async_wait in the handler of the first.

Upvotes: 1

Related Questions