AgentXcpp  Revision:0.1.1
Internals Documentation
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Pages
timeout_timer.cpp
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 
20 #include <boost/bind.hpp>
21 
22 #include "timeout_timer.hpp"
23 
24 
25 using namespace agentxcpp;
26 
27 std::set<timeout_timer*> timeout_timer::available_timers;
28 
29 // Throws boost::system::system_error:
30 timeout_timer::timeout_timer(boost::asio::io_service & io_service)
31  : status(standby),
32  timer(io_service)
33 {
34  try
35  {
36  // Throws boost::system::system_error:
37  timer.expires_at(boost::posix_time::pos_infin);
38  }
39  catch(boost::system::system_error)
40  {
41  // Timer broke
42  status = broken;
43  }
44 
45  // Start timer
46  timer.async_wait(boost::bind(&timeout_timer::check_deadline, this));
47 
48  available_timers.insert(this);
49 }
50 
51 // Throws boost::system::system_error:
52 void timeout_timer::expires_at(boost::asio::deadline_timer::time_type time)
53 {
54  if(status == broken)
55  {
56  // Object is broken -> do nothing
57  return;
58  }
59 
60  status = running;
61 
62  try
63  {
64  // Throws boost::system::system_error:
65  timer.expires_at(time);
66  }
67  catch(boost::system::system_error)
68  {
69  // Timer broke
70  status = broken;
71  }
72 }
73 
74 
75 // Throws boost::system::system_error:
76 void timeout_timer::expires_from_now(boost::asio::deadline_timer::duration_type duration)
77 {
78  if(status == broken)
79  {
80  // Object is broken -> do nothing
81  return;
82  }
83 
84  status = running;
85 
86  try
87  {
88  // Throws boost::system::system_error:
89  timer.expires_from_now(duration);
90  }
91  catch(boost::system::system_error)
92  {
93  // Timer broke
94  status = broken;
95  }
96 }
97 
98 
99 // Throws boost::system::system_error:
101 {
102  if(self->available_timers.find(self) == self->available_timers.end())
103  {
104  // The timer was already destroyed
105  return;
106  }
107 
108  if(self->status == broken)
109  {
110  // Object is broken, -> do nothing (not even restart the timer)
111  return;
112  }
113 
114  // Check whether the deadline has passed. We compare the deadline against
115  // the current time since a new asynchronous operation may have moved the
116  // deadline before this callback had a chance to run.
117  if (self->timer.expires_at() <= boost::asio::deadline_timer::traits_type::now())
118  {
119 
120  // The deadline has passed.
121  // -> set status to "expired"
122  self->status = expired;
123 
124  // There is no longer an active deadline. The expiry is set to positive
125  // infinity so that the callback is not invoked until a new deadline is
126  // set.
127  try
128  {
129  // Throws boost::system::system_error:
130  self->timer.expires_at(boost::posix_time::pos_infin);
131  }
132  catch(boost::system::system_error)
133  {
134  // Object broke
135  self->status = broken;
136 
137  // No further processing
138  return;
139  }
140 
141  }
142 
143  // Re-start timer
144  self->timer.async_wait(boost::bind(&timeout_timer::check_deadline, self));
145 }
146 
147 
148 // Throws boost::system::system_error:
150 {
151  if(status == broken)
152  {
153  // Object is broken, -> do nothing (not even restart the timer)
154  return;
155  }
156 
157  status = standby;
158 
159  try
160  {
161  // Throws boost::system::system_error:
162  timer.expires_at(boost::posix_time::pos_infin);
163  }
164  catch(boost::system::system_error)
165  {
166  // Timer broke
167  status = broken;
168  }
169 }
170 
171 
173 {
174  available_timers.erase(this);
175 }