asio 0.1.5 Main Page | Class Index | Member Index | Tutorial

Tutorial Part 3 - Binding arguments to a handler

In this part of the tutorial we will modify the program from Part 2 so that the timer fires once a second. This will show how to pass additional parameters to a your handler function.

#include <iostream>
#include "boost/bind.hpp"
#include "asio.hpp"

Step 1. To implement a repeating timer using asio you need to change the timer's expiry time in your callback function, and to then start a new asynchronous wait. Obviously this means that the callback function will need to be able to access the timer object. To this end we add two new parameters to the print function:

void print(asio::timer* t, int* count)
{

Step 2. As mentioned above, this tutorial program uses a counter to stop running when the timer fires for the sixth time. However you will observe that there is no explicit call to ask the demuxer to stop. Recall that in Part 2 we learnt that the asio::demuxer::run() function completes when there is no more "work" to do. By not starting a new asynchronous wait on the timer when count reaches 5, the demuxer will run out of work and stop running.

  if (*count < 5)
  {
    std::cout << *count << "\n";
    ++(*count);

Step 3. Next we move the expiry time for the timer along by one second from the previous expiry time. Using the asio::timer::from_existing flag instead of asio::timer::from_now ensures that the timer does drift away from the whole-second mark due to any delays in processing the handler.

    t->set(asio::timer::from_existing, 1);

Step 4. Then we start a new asynchronous wait on the timer. As you can see, the boost::bind function is used to associate the extra parameters with your callback handler. The asio::timer::async_wait() function expects a handler function (or function object) with the signature void(). Binding the additional parameters converts your print function into a function object that matches the signature correctly.

    t->async_wait(boost::bind(print, t, count));
  }
}

int main()
{
  asio::demuxer d;

Step 5. A new count variable is added so that we can stop the program when the timer fires for the sixth time.

  int count = 0;
  asio::timer t(d, asio::timer::from_now, 1);

Step 6. As in Step 4, when making the call to asio::timer::async_wait() from main we bind the additional parameters needed for the print function.

  t.async_wait(boost::bind(print, &t, &count));

  d.run();

Step 7. Finally, just to prove that the count variable was being used in the print handler function, we will print out its new value.

  std::cout << "Final count is " << count << "\n";

  return 0;
}

See the Source listing for Tutorial Part 3
Return to the Tutorial Index
Go back to Tutorial Part 2 - Using a timer asynchronously
Go on to Tutorial Part 4 - Using a member function as a handler