1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/variant.hpp>
#include <boost/bind.hpp>
class CTimeout {
public :
CTimeout() : m_Timeout(0)
{
m_pTimer.reset(new boost::asio::deadline_timer(m_IoServ));
m_bStarted = false;
};
virtual ~CTimeout() {
Stop();
};
/**
* Set timer timeout
* @param p_Timeout in millisecond
*/
void SetTimeout(size_t p_Timeout) {
m_Timeout = p_Timeout;
};
/**
* start timer
*/
void Start() {
if (m_Timeout) {
m_pTimer->expires_from_now(boost::posix_time::milliseconds(m_Timeout),m_ec);
//m_pTimer->async_wait(boost::bind(&CTimeout::CallCallback,boost::ref(*this),boost::asio::placeholders::error));
//m_pTimer->async_wait(boost::bind(&CTimeout::CallCallback,boost::ref(*this),_1));
m_pTimer->async_wait(boost::bind(&CTimeout::callCallback,this,boost::asio::placeholders::error));
m_bStarted=true;
m_IoServ.run();
}
};
void Start(size_t p_Timeout) {
SetTimeout(p_Timeout);
Start();
}
/**
* stop timer
*/
void Stop() {
m_pTimer->cancel(m_ec);
};
/**
* restart timer
*/
void Restart() {
TRACE("CTimeout::Restart())\n");
if (m_bStarted)
m_pTimer->expires_from_now(boost::posix_time::milliseconds(m_Timeout),m_ec);
else
Start();
};
void Restart(size_t p_Timeout) {
TRACE("CTimeout::Restart(size_t p_Timeout))\n");
m_Timeout = p_Timeout;
if (m_bStarted)
m_pTimer->expires_from_now(boost::posix_time::milliseconds(m_Timeout),m_ec);
else Start(p_Timeout);
};
/**
* Timeout callback
*/
typedef void(*TTimeoutCallback)(void *p_pTarget);
void SetCallback(TTimeoutCallback p_pCB, void *p_pCallbackParameter) {
SCallbackStruct l_CbStruct;
l_CbStruct.m_pFunction = p_pCB;
l_CbStruct.m_pCallbackParam = p_pCallbackParameter;
m_Callbacks=l_CbStruct;
};
typedef boost::function<void (void)> TCallbackFunctor;
void SetCallback(TCallbackFunctor &p_pCB) {
m_Callbacks = p_pCB;
};
void SetCallback(TCallbackFunctor p_pCB) {
m_Callbacks = p_pCB;
};
protected:
boost::shared_ptr<boost::asio::deadline_timer> m_pTimer;
boost::asio::io_service m_IoServ;
size_t m_Timeout;
boost::system::error_code m_ec;
///! must do this way because callback must be void CB(const boost::system::error_code& error) !!
void callCallback(const boost::system::error_code &error) {
TRACE("FILE <%s>, LINE %d -> param = %d\n",__FILE__, __LINE__,error);
if (error != boost::asio::error::operation_aborted)
{
// Timer was not cancelled, take necessary action.
if( SCallbackStruct* l_pStruct = boost::get<SCallbackStruct>(&m_Callbacks) ) {
if (l_pStruct->m_pFunction && l_pStruct->m_pCallbackParam) {
(*l_pStruct->m_pFunction)(l_pStruct->m_pCallbackParam);
}
}
else if (TCallbackFunctor *l_pFunct = boost::get<TCallbackFunctor>(&m_Callbacks) ) {
(*l_pFunct)();
}
}
};
///!
// Callback memorization structure. Required to used boost::variant
typedef struct SCallbackStruct
{
TTimeoutCallback m_pFunction;
void *m_pCallbackParam;
SCallbackStruct() : m_pFunction(0),m_pCallbackParam(0)
{ };
};
typedef struct boost::variant<SCallbackStruct, TCallbackFunctor> TCallbacks;
TCallbacks m_Callbacks;
bool m_bStarted;
}; |
Partager