GameServer
basic_repeating_timer.h
[詳解]
1 #ifndef BOOST_ASIO_REPEATING_TIMER_H_INCLUDED
2 #define BOOST_ASIO_REPEATING_TIMER_H_INCLUDED
3 
4 
5 // Developed 2007 by David C. Wyles (http:///www.codegorilla.co.uk)
6 // released for public consumption under the same
7 // licensing policy as the boost library http://www.boost.org/LICENSE_1_0.txt
8 //
9 // most people will use the repeating_timer typedef for working with posix time
10 //
11 // Is is based on the basic_deadline_timer
12 //
13 
14 #include <boost/bind.hpp>
15 #include <boost/noncopyable.hpp>
16 #include <boost/asio.hpp>
17 #include <boost/date_time/posix_time/posix_time.hpp>
18 #include <boost/thread/recursive_mutex.hpp>
19 #include <boost/thread/condition.hpp>
20 #include <boost/shared_ptr.hpp>
21 #include <boost/enable_shared_from_this.hpp>
22 #include <boost/weak_ptr.hpp>
23 
24 
25 namespace boost
26 {
27 namespace asio
28 {
29  // basic repeating timer with start stop semantics.
30 
31 
32  template <typename Time,
33  typename TimeTraits = boost::asio::time_traits<Time>,
34  typename TimerService = boost::asio::detail::deadline_timer_service<TimeTraits> >
35  class basic_repeating_timer : public boost::asio::basic_io_object<TimerService>
36  {
37  public:
38  typedef boost::asio::basic_deadline_timer<Time> timer_type;
39 
40 
41  explicit basic_repeating_timer( boost::asio::io_service& io_service )
42  : boost::asio::basic_io_object<TimerService>(io_service)
43  {
44  }
45 
46 
48  {
49  stop();
50  }
51 
52 
53  template <typename WaitHandler>
54  void start( typename timer_type::duration_type const & repeat_interval, WaitHandler handler )
55  {
56  boost::recursive_mutex::scoped_lock guard(lock_);
57  {
58  // cleanup code, cancel any existing timer
59  handler_.reset();
60  if( timer_ )
61  {
62  timer_->cancel();
63  }
64  timer_.reset();
65  }
66 
67 
68  // create new handler.
69  handler_.reset( new handler_impl<WaitHandler>( handler ) );
70  // create new timer
71  timer_ = internal_timer::create( /* this->IoService() */ this->get_io_service(), repeat_interval, handler_ );
72  }
73 
74  void stop()
75  {
76  boost::recursive_mutex::scoped_lock guard(lock_);
77  {
78  // cleanup code.
79  handler_.reset();
80  if( timer_ )
81  {
82  timer_->cancel();
83  }
84  timer_.reset();
85  }
86  }
87 
88 
89  void cancel() {stop();}
90 
91 
92  // changes the interval the next time the timer is fired.
93  void change_interval( typename timer_type::duration_type const & repeat_interval )
94  {
95  boost::recursive_mutex::scoped_lock guard(lock_);
96  if( timer_ )
97  {
98  timer_->change_interval( repeat_interval );
99  }
100  }
101 
102 
103  private:
104 
105 
106  boost::recursive_mutex lock_;
107  class internal_timer;
108  typedef boost::shared_ptr<internal_timer> internal_timer_ptr;
109  internal_timer_ptr timer_;
110 
111  class handler_base;
112  boost::shared_ptr<handler_base> handler_;
113 
114 
115 
116  class handler_base
117  {
118  public:
119  virtual ~handler_base() {}
120  virtual void handler( boost::system::error_code const & ) = 0;
121  };
122 
123 
124  template <typename HandlerFunc>
125  class handler_impl : public handler_base
126  {
127  public:
128  handler_impl( HandlerFunc func ) : handler_func_(func) {}
129  virtual void handler( boost::system::error_code const & result )
130  {
131  handler_func_(result);
132  }
133  HandlerFunc handler_func_;
134  };
135 
136 
137  class internal_timer : public boost::enable_shared_from_this<internal_timer>
138  {
139  public:
140  static internal_timer_ptr create( boost::asio::io_service& io_service,
141  typename timer_type::duration_type const & repeat_interval,
142  boost::shared_ptr<handler_base> const & handler )
143  {
144  internal_timer_ptr timer( new internal_timer( io_service ) );
145  timer->start( repeat_interval, handler );
146  return timer;
147  }
148 
149 
150  void cancel()
151  {
152  boost::recursive_mutex::scoped_lock guard( lock_ );
153  timer_.cancel();
154  }
155 
156 
157  void change_interval( typename timer_type::duration_type const & repeat_interval )
158  {
159  boost::recursive_mutex::scoped_lock guard( lock_ );
160  interval_ = repeat_interval;
161  }
162 
163 
164  private:
165  timer_type timer_;
166  boost::weak_ptr<handler_base> handler_;
167  typename timer_type::duration_type interval_;
168  boost::recursive_mutex lock_;
169 
170 
171  internal_timer( boost::asio::io_service& io_service )
172  :timer_(io_service)
173  {
174  }
175 
176 
177  void start( typename timer_type::duration_type const & repeat_interval,
178  boost::shared_ptr<handler_base> const & handler )
179  {
180  // only EVER called once, via create
181  interval_ = repeat_interval;
182  handler_ = handler;
183 
184 
185  timer_.expires_from_now( interval_ );
186  timer_.async_wait( boost::bind( &internal_timer::handle_timeout, this->shared_from_this(), boost::asio::placeholders::error ) );
187  }
188 
189 
190  void handle_timeout(boost::system::error_code const& error)
191  {
192  // we lock in the timeout to block the cancel operation until this timeout completes
193  boost::recursive_mutex::scoped_lock guard( lock_ );
194  {
195  // do the fire.
196  boost::shared_ptr<handler_base> Handler = handler_.lock();
197  if( Handler )
198  {
199  try
200  {
201  Handler->handler(error);
202  }
203  catch( std::exception const & e )
204  {
205  // consume for now, no much else we can do, we don't want to damage the
206  // io_service thread
207  (void)e;
208  }
209  }
210  }
211 
212  if( !error )
213  {
214  // check if we need to reschedule.
215  boost::shared_ptr<handler_base> Handler = handler_.lock();
216  if( Handler )
217  {
218  timer_.expires_from_now( interval_ );
219  //m_Timer.expires_at( m_Timer.expires_at() + m_Repeat_Interval );
220  timer_.async_wait( boost::bind( &internal_timer::handle_timeout, this->shared_from_this(), boost::asio::placeholders::error ) );
221  }
222  }
223  }
224  };
225  };
226 
227 
229 }
230 }
231 
232 
233 #endif
Definition: basic_repeating_timer.h:25
void change_interval(typename timer_type::duration_type const &repeat_interval)
Definition: basic_repeating_timer.h:93
~basic_repeating_timer()
Definition: basic_repeating_timer.h:47
void cancel()
Definition: basic_repeating_timer.h:89
basic_repeating_timer(boost::asio::io_service &io_service)
Definition: basic_repeating_timer.h:41
boost::asio::basic_deadline_timer< Time > timer_type
Definition: basic_repeating_timer.h:38
void start(typename timer_type::duration_type const &repeat_interval, WaitHandler handler)
Definition: basic_repeating_timer.h:54
basic_repeating_timer< boost::posix_time::ptime > repeating_timer
Definition: basic_repeating_timer.h:228
Definition: basic_repeating_timer.h:35
void stop()
Definition: basic_repeating_timer.h:74