Hi all,
I started playing with ASIO timers and after scanning through the relevant docs, I set up a small case. Please find below the code snippet.
The IntervalEvent class is supposed to fire the event provided on the construction at a frequency equal to the durationInterval.
Somehow the code below fails to compile on VC7.1.
I am getting several warnings and the error:
c:\program files\boost\boost_1_38\boost\mem_fn.hpp(343) : error C4716: 'boost::_mfi::dm<void __thiscall IntervalEvent::(boost::system::error_code &),IntervalEvent>::operator()' : must return a value
I have not tried yet gcc. Probably I am doing something stupid. Any ideas?
Further to that, I am wondering, in principle should I cancel the deadline_timer on the destructor of the IntervalEvent class? Does the io_service class know when any of the deadline_timers that is being registered goes out of scope?
Thank you very much in advance. Any help would be highly appreciated.
Kimon
#include <boost/function.hpp>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
class Counter
{
public:
Counter():m_value(0)
{
}
void onIncrement()
{
++m_value;
std::cout<<"Counter is "<<m_value<<std::endl;
}
protected:
int m_value;
};
class IntervalEvent
{
public:
IntervalEvent(boost::asio::io_service &io,
long durationSeconds,
boost::function<void(void)> event):
m_intervalDuration(durationSeconds),
m_timer(io,boost::posix_time::seconds(m_intervalDuration)),
m_event(event)
{
//io_service::run is running in only one thread
m_timer.async_wait(boost::bind(&IntervalEvent::handler, this));
}
~IntervalEvent()
{
//should I call m_timer.cancel to notify the io_service?
}
void handler(boost::system::error_code& error)
{
if(error!= boost::asio::error::operation_aborted)
{
m_event();
reset(m_intervalDuration);
}
}
void reset(long duration)
{
if (m_timer.expires_from_now(boost::posix_time::seconds(duration)) > 0)
{
m_intervalDuration = duration;
//reset the async wait
m_timer.async_wait(boost::bind(&IntervalEvent::handler, this));
}
else
{
//Timer already canceled
}
}
void cancel()
{
m_timer.cancel();
}
size_t getCurrentInterval() const
{
return m_intervalDuration;
}
protected:
long m_intervalDuration;
boost::asio::deadline_timer m_timer;
boost::function<void(void)> m_event;
};
int main()
{
boost::asio::io_service io;
boost::shared_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(io));
boost::thread ioservice_thread(boost::bind(&boost::asio::io_service::run, &io));
std::vector<boost::shared_ptr<IntervalEvent> > events;
Counter count;
long duration = 1;
boost::shared_ptr<IntervalEvent> firstEvent(new IntervalEvent(io,
duration,
boost::bind(&Counter::onIncrement,boost::ref(count)
))
);
events.push_back(firstEvent);
char response = 'N';
while(response == 'N')
{
std::cout<<"Create a new interval event? [Y/N]"<<std::endl;
std::cin>>response;
if(response == 'Y')
{
boost::shared_ptr<IntervalEvent> test(new IntervalEvent(io,
duration,
boost::bind(&Counter::onIncrement,boost::ref(count)
))
);
events.push_back(test);
}
}
//cancel interval events
for(std::vector<boost::shared_ptr<IntervalEvent> >::iterator it = events.begin(), itEnd = events.end();
it!=itEnd;
++it)
{
(*it)->cancel();
}
//reset ioservice_work
work.reset();
ioservice_thread.join();
return 0;
}