AgentXcpp
Revision:0.1.1
Internals Documentation
All
Classes
Namespaces
Files
Functions
Variables
Enumerations
Enumerator
Friends
Pages
timeout_timer.hpp
Go to the documentation of this file.
1
/*
2
* Copyright 2011-2012 Tanjeff-Nicolai Moos <tanjeff@cccmz.de>
3
*
4
* This file is part of the agentXcpp library.
5
*
6
* AgentXcpp is free software: you can redistribute it and/or modify
7
* it under the terms of the AgentXcpp library license, version 1, which
8
* consists of the GNU General Public License and some additional
9
* permissions.
10
*
11
* AgentXcpp is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* See the AgentXcpp library license in the LICENSE file of this package
17
* for more details.
18
*/
19
#ifndef _TIMEOUT_TIMER_H_
20
#define _TIMEOUT_TIMER_H_
21
22
23
#include <set>
24
#include <boost/asio.hpp>
25
26
namespace
agentxcpp
27
{
28
/**
29
* \internal
30
*
31
* \brief A timer which can detect timeouts
32
*
33
* This timer can detect timeouts. A timeout_timer object starts in
34
* "standby" state. The timer can then be started using the expires_at()
35
* (giving an absolute time) or expires_from_now() (giving a time span)
36
* methods, which changes the status to "running". When the timer expires,
37
* the status changes to "expired". The timer can be disabled at any time
38
* using cancel(), which changes the status back to "standby" (this works
39
* also with an expired timer).
40
*
41
* This class uses the boost::asio library and therefore needs an
42
* io_service object. It never calls io_service::run() or
43
* io_service::run_one(). For the timeout_timer to work, the run() or
44
* run_one() method of the io_service object must be invoked by the user of
45
* timeout_timer. As long as neither of them are invoked, the timer will
46
* not report the status "expired".
47
*
48
* The object can break, e.g. when something with the interally used
49
* boost::asio::deadline_timer goes wrong. In this case the status changes
50
* to "broken". A broken timeout_timer cannot be used anymore: a call to
51
* any member function will do nothing (except for get_status(), which will
52
* report the status "broken") and the status will be "broken" forever.
53
*
54
* \par How it works
55
*
56
* For timeout detection, an asio deadline_timer is used together with the
57
* status member. While the timer is not in use, it's expiry time is set to
58
* "infinite" and status is set to "standby". When starting the timer, the
59
* deadline_timer's expiry is set to the according time, and status is set
60
* to "running". If the deadline_timer expires, it invokes the
61
* check_deadline() callback, which sets the expiry back to "infinite" and
62
* status to "expired". If cancel() is invoked before the deadline_timer
63
* expires, the expiry is set back to "infinite" and the status to
64
* "standby".
65
*
66
* The check_deadline() callback may be invoked errornously, e.g. when the
67
* deadline_timer's expiry time is reset after the timer expired, but
68
* before the callback actually is invoked. Therefore, check_deadline()
69
* compares the expiry date of the timer with the current timestamp to
70
* determine whether the timer really expired.
71
*
72
* Also, check_deadline() is called after the deadline_timer object is
73
* destroyed. This happens when a timeout_timer object is destroyed, which
74
* means that the callback function must not be a member function. Instead
75
* it is a static class function which takes a pointer to the timeout_timer
76
* object for which it is called. To identify calls for destroyed objects,
77
* the static mamber "available_timers" is used, which stores pointers to
78
* all timeout_timer objects currently in existence. This is handled by the
79
* constructors and destructor of the timeout_timer class.
80
*/
81
class
timeout_timer
82
{
83
public
:
84
85
/**
86
* \brief Constructor
87
*
88
* This constructor sets the timer status to "standby", the
89
* deadline_timer's expiry to "infinite" and add the new object to
90
* "available_timers". It also starts the deadline_timer.
91
*
92
* \note If something goes wrong, the status is set to "broken".
93
*
94
* \param io_service The io_service object which will be used by
95
* the timer.
96
*
97
* \exception None.
98
*/
99
timeout_timer
(boost::asio::io_service & io_service);
100
101
/**
102
* \brief The timeout status type.
103
*/
104
enum
status_t
105
{
106
running
,
// timer is running
107
expired
,
// timer expired
108
standby
,
// timer currently not in use
109
broken
// timer is broken
110
};
111
112
/**
113
* \brief Time out at the given time.
114
*
115
* This function starts the timer and set its expiry time to
116
* 'time'. The status is set to 'running'.
117
*
118
* \note If something goes wrong, the status is set to "broken".
119
*
120
* \param time The time at which the timer shall expire.
121
*
122
* \exception None.
123
*/
124
void
expires_at
(boost::asio::deadline_timer::time_type time);
125
126
/**
127
* \brief Time out at (now + duration).
128
*
129
* This function starts the deadline_timer and sets its expiry time
130
* to (now + 'duration'). The status is set to 'running'.
131
*
132
* \note If something goes wrong, the status is set to "broken".
133
*
134
* \param duration The duration after which the timer elapses.
135
*
136
* \exception None.
137
*/
138
void
expires_from_now
(boost::asio::deadline_timer::duration_type duration);
139
140
/**
141
* \brief Stop the timer.
142
*
143
* This stops the timer. The status is set to "standby", and the
144
* deadline_timer's expiry time is set to "infinite".
145
*
146
* \note If something goes wrong, the status is set to "broken".
147
*
148
* \exception None.
149
*/
150
void
cancel
();
151
152
/**
153
* \brief Get the current timer status.
154
*
155
* \exception None.
156
*/
157
status_t
get_status
()
158
{
159
return
status
;
160
}
161
162
/**
163
* \brief Destructor
164
*
165
* The destructor removes the object from "available_timers".
166
*/
167
~timeout_timer
();
168
169
private
:
170
171
/**
172
* \brief Set of timeout_timer objects currently in existence.
173
*/
174
static
std::set<timeout_timer*>
available_timers
;
175
176
/**
177
* \brief Hide default constructor.
178
*
179
* We need an io_service object to function properly.
180
*/
181
timeout_timer
();
182
183
/**
184
* \brief The timeout status.
185
*/
186
status_t
status
;
187
188
/**
189
* \brief The boost::asio timer.
190
*
191
* This timer is used to detect timeout conditions.
192
*/
193
boost::asio::deadline_timer
timer
;
194
195
/**
196
* \brief The timeout handler.
197
*
198
* This function is used as callback handler for 'timer'. It
199
* compares the deadline_timer's expiry time with the current
200
* system time to detect errornous invokation. It also checks
201
* whether the timeout_timer object exists (and does nothing if
202
* not). If a real timeout is detected, the status is set to
203
* "expired" and the deadline_timer's expiry is set to
204
* "infinite".
205
*
206
* This callback also restarts the timer on each call to keep it
207
* running.
208
*
209
* If something goes wrong, the status is set to "broken".
210
*
211
* \param self The timeout_timer object which triggered the
212
* callback.
213
*/
214
static
void
check_deadline
(
timeout_timer
*
self
);
215
};
216
}
217
218
#endif
src
timeout_timer.hpp
Generated by
1.8.1.1