Reputation: 16486
I need to be able to test that after an expiry time a function is called. After this failed to work I wrote a small MCE that demonstrates the essentials of the test. It returns without firing the handler.
Uncomment the line below 'is there a handler to expire?' causes it echo 1 to the console which means there is an unexpired handler.
According to the documentation the
The handler will be called when:
- The timer has expired.
- The timer was cancelled, in which case the handler is passed the error code boost::asio::error::operation_aborted.
So I think I should at least get 'handler' echoed to the screen when that line is uncommented.
Worryingly if you move it after the sleep_for
and yield
lines there is still a handler active.
Why isn't my timer firing?
MCE:
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <iostream>
#include <thread>
void handler(const boost::system::error_code& error)
{
std::cout << "handler." << std::endl;
if (!error)
{
std::cout << "Timer expired." << std::endl;
}
}
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
// Construct a timer without setting an expiry time.
boost::asio::steady_timer timer(io_service);
// expire immediately
timer.expires_from_now(std::chrono::seconds(0));
// Wait for the timer to expire.
timer.async_wait(handler);
// is there a handler to expire?
// std::cout << "Expiry : " << timer.expires_from_now(std::chrono::seconds(1)) << std::endl;
// added to allow the timer to expire
std::this_thread::sleep_for(std::chrono::seconds(2));
std::this_thread::yield();
}
Upvotes: 3
Views: 2800
Reputation: 2124
Problem
You are using the asynchronous variant of wait
without calling io_service.run();
This call is required because operating system-specific functions have to take over control. Remember that it is the I/O service in the I/O service object which implements asynchronous operations based on operating system-specific functions.
Solution
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
// Construct a timer without setting an expiry time.
boost::asio::steady_timer timer(io_service);
// expire immediately
timer.expires_from_now(std::chrono::seconds(0));
// Wait for the timer to expire.
timer.async_wait(handler);
io_service.run();
}
Upvotes: 2