//
// fox_timer.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2014-2015 yoen.xu (181471112 at qq dot com)
//
//说明:该类线程安全
//eg:
// 启动: fox_timer<T>::run(io_, func, interval);运行一个定时器:T 为func的返回类型,当T为int的时候(范围值-1代表取消定时器,0定时器时间不变 >0重置定时器时间)
// 停止: fox_timer<T>::stop_all();取消所有定时器(在io退出之前要先调用)
#ifndef FOX_TIMER_HPP
#define FOX_TIMER_HPP
#if defined(_MSC_VER) && (_MSC_VER >=1200)
#pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/asio.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_types.hpp>
#include <list>
using namespace boost;
using namespace boost::asio;
namespace thefox{
template <typename ReturnType>
class fox_timer:public boost::enable_shared_from_this< fox_timer<ReturnType> >{
public:
typedef boost::function<ReturnType()> func_t;
typedef boost::shared_ptr< fox_timer<ReturnType> > type;
static std::list<type> timer_list_ ;
static boost::mutex mutex_;
static size_t s_use_;
static void run(io_service& ios,func_t func,const long seconds=DEFAULT_INTERVAL_SECONDS){
type ptr = boost::make_shared< fox_timer<ReturnType> >(ios, func,seconds);
if (ptr)
{
{
boost::unique_lock<boost::mutex> lock(mutex_);
fox_timer<ReturnType>::timer_list_.push_back(ptr);
++s_use_;
}
ptr->start();
}else
throw std::runtime_error("run unbound fox_timer");
}
static void stop_all(){
boost::unique_lock<boost::mutex> lock(mutex_);
for (std::list<type>::iterator itr=timer_list_.begin(); itr!=timer_list_.end();)
{
(*itr)->cancle();
itr = timer_list_.erase(itr);
--s_use_;
}
}
explicit fox_timer(io_service& ios, func_t func, const long seconds=DEFAULT_INTERVAL_SECONDS)
:f_(func),interval_(seconds)
,t_(ios,posix_time::seconds(seconds))
{
assert(typeid(boost::result_of<func_t()>::type) == typeid(ReturnType));
}
~fox_timer()
{
cancle();
}
void set_interval(const long seconds){
interval_ = seconds;
}
void start(){
do_wait();
}
private:
//default dead time(seconds)
const static long DEFAULT_INTERVAL_SECONDS = 3;
func_t f_;
//async_wait callback function
deadline_timer t_;
long interval_;
void cancle(){
t_.cancel();
}
void do_wait(){
t_.expires_from_now(posix_time::seconds(interval_));
t_.async_wait(boost::bind(&fox_timer::call_func,shared_from_this(),boost::asio::placeholders::error));
}
void call_func(const system::error_code& err){
if (err){
return;
}
else{
assert(!f_.empty());
f_();
do_wait();
}
}
};
template <typename ReturnType> boost::mutex fox_timer<ReturnType>::mutex_ ;
template <typename ReturnType> std::list< typename fox_timer<ReturnType>::type > fox_timer<ReturnType>::timer_list_ ;
template <typename ReturnType> size_t fox_timer<ReturnType>::s_use_=0;
//模板成员函数特化
template<>
void fox_timer<int>::call_func(const system::error_code& err){
if (err){
return;
}
else{
assert(!f_.empty());
int iret = f_();
assert(iret >= -1);
switch(iret){
case -1:
return;
case 0:
break;
default:
set_interval(iret);
}
do_wait();
}
}
}//namespace fox
#endif //FOX_TIMER_HPP
共享boost::deadline_timer封装模板,可以接受任何函数对象
最新推荐文章于 2023-04-05 00:46:23 发布