Bonjour,

je veux faire une classe timeout qui permet de "declencher" l'appel d'une fontion apres qu'un temps donné soit ecoulé.
Pour ca, j'utilise Boost.Asio

Dans un test, je fais ca :
  1. mesurer TimeStart;
  2. demarrer le timer pour 5 secondes
  3. attendre 2 secondes
  4. redemarrer le timer pour 5 secondes (donc on interrompt le timer)
  5. mesurer TimeStop
  6. Verifier que TimeStop-TimeStart est de l'ordre de 7 secondes.


Qd je regarde de plus pres les valeurs de error lors de l'appel de callCallback(const boost::system::error_code &error), error vaut toujours 0.
Or, d'apres la doc, lorsque de redemarrer le timer (etape 4), je devrais recevoir boost::asio::error::operation_aborted mais ce n'est pas la cas.
J'ai donc un doute sur le fonctionnement de mon timer.

Une idée de la part de quelqu'un ?

Ci-dessous le code du composant 'timer'.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;
};