acl  3.5.3.0
trigger.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include <map>
4 #include <vector>
5 #include "noncopyable.hpp"
6 #include "mbox.hpp"
7 #include "util.hpp"
8 #include "thread.hpp"
9 #include "thread_mutex.hpp"
10 
11 namespace acl {
12 
13 /**
14  * 具有相同时间截的定时任务的集合
15  */
16 template <typename T>
17 class trigger_item : public noncopyable
18 {
19 public:
20  typedef std::map<long long, trigger_item<T>*> trigger_items_t;
21 
22  trigger_item(trigger_items_t& items) : items_(items) {}
23  ~trigger_item(void) {}
24 
25  /**
26  * 添加一个定时任务
27  * @pararm o {T*}
28  */
29  void add(T* o)
30  {
31  objs_.push_back(o);
32  }
33 
34  /**
35  * 删除一个具有相同时间截的定时任务
36  * @pararm o {T*}
37  * @return {int} 返回值 >= 0 表示剩余的具有相同时间截的定时任务数,
38  * 返回 -1 表示该定时任务不存在
39  */
40  int del(T* o)
41  {
42  for (typename std::vector<T*>::iterator it = objs_.begin();
43  it != objs_.end(); ++it) {
44 
45  if (*it == o) {
46  objs_.erase(it);
47  return (int) objs_.size();
48  }
49  }
50  return -1;
51  }
52 
53  /**
54  * 获取具有相同时间截的所有定时任务集合
55  * @return {std::vector<T*>&}
56  */
57  std::vector<T*>& get_objs(void)
58  {
59  return objs_;
60  }
61 
62 private:
63  std::vector<T*> objs_;
64  trigger_items_t& items_;
65 };
66 
67 /**
68  * 定时任务触发管理器,通过本类添加定时任务,该类会将到期的任务进行触发
69  * 每个定时任务对象 T 需要实现以下方法,以便于由该触发器触发
70  *
71  * bool on_trigger(void); // 定时时间到期时的回调方法,返回值表示
72  * // 是否需要再次触发该定时任务
73  * int get_ttl(void) const; // 定时任务到达时的时间间隔(毫秒)
74  * void set_key(long long key); // 触发器设置与该定时任务关联的键
75  * long long get_key(void) const; // 获得由 set_key 设置的键
76  *
77  * 如一个 T 的实例类声明如下:
78  * class mytask
79  * {
80  * public:
81  * mytask(void) {}
82  * ~mytask(void) {}
83  *
84  * // @override
85  * bool on_trigger(void)
86  * {
87  * return true;
88  * }
89  *
90  * // @override
91  * int get_ttl(void) const
92  * {
93  * return 1000;
94  * }
95  *
96  * // @override
97  * void set_key(long long key)
98  * {
99  * key_ = key;
100  * }
101  *
102  * // @override
103  * long long get_key(void) const
104  * {
105  * return key_;
106  * }
107  *
108  * private:
109  * long long key_;
110  * };
111  */
112 template <typename T>
114 {
115 public:
116  typedef std::map<long long, trigger_item<T>*> trigger_items_t;
117  typedef typename trigger_items_t::iterator trigger_iter_t;
118 
119  timer_trigger(void) {}
120  ~timer_trigger(void) {}
121 
122  /**
123  * 添加一个任务对象
124  * @pararm o {T*}
125  */
126  void add(T* o)
127  {
128  int ttl = o->get_ttl();
129  long long key = get_curr_stamp() + ttl;
130 
131  trigger_item<T>* item;
132  trigger_iter_t it = items_.find(key);
133  if (it == items_.end()) {
134  item = new trigger_item<T>(items_);
135  items_[key] = item;
136  } else
137  item = it->second;
138  item->add(o);
139  o->set_key(key);
140  }
141 
142  /**
143  * 删除一个任务对象,内部调用 o->get_key() 方法获得该任务对象的键
144  * @pararm o {T*} 指定将被删除的任务对象
145  * @return {int} >= 0 时表示剩余的任务对象,-1 表示该任务对象不存在
146  */
147  int del(T* o)
148  {
149  long long key = o->get_key();
150  trigger_iter_t it = items_.find(key);
151 
152  if (it == items_.end())
153  return -1;
154  if (it->second->del(o) == 0) {
155  delete it->second;
156  items_.erase(it);
157  }
158  return (int) items_.size();
159  }
160 
161  /**
162  * 触发所有到期的定时任务
163  * @return {long long} 返回下一个将被触发的定时任务的时间截,返回 -1
164  * 表示没有定时任务
165  */
166  long long trigger(void)
167  {
168  long long key = get_curr_stamp();
169  std::vector<trigger_item<T>*> items;
170  trigger_iter_t iter;
171  for (iter = items_.begin(); iter != items_.end();) {
172  if (iter->first > key)
173  break;
174 
175  items.push_back(iter->second);
176  items_.erase(iter++);
177  }
178 
179  for (typename std::vector<trigger_item<T>*>::iterator
180  it = items.begin(); it != items.end(); ++it) {
181 
182  trigger(*it);
183  delete *it;
184  }
185 
186  iter = items_.begin();
187  if (iter == items_.end())
188  return -1;
189  return iter->first;
190  }
191 
192 private:
193  trigger_items_t items_;
194 
195  /**
196  * 触发具有相同定时时间截的所有任务
197  * @pararm item {trigger_item<T>*}
198  */
199  void trigger(trigger_item<T>* item)
200  {
201  std::vector<T*>& objs = item->get_objs();
202  for (typename std::vector<T*>::iterator it = objs.begin();
203  it != objs.end(); ++it) {
204 
205  if (!(*it)->on_trigger())
206  continue;
207 
208  int ttl = (*it)->get_ttl();
209  long long key = get_curr_stamp() + ttl;
210 
211  trigger_iter_t iter = items_.find(key);
212  if (iter == items_.end()) {
213  item = new trigger_item<T>(items_);
214  items_[key] = item;
215  } else
216  item = iter->second;
217 
218  item->add(*it);
219  (*it)->set_key(key);
220  }
221  }
222 };
223 
224 /**
225  * 定时器管理线程,该线程从 mbox 中获得定时任务,并加入定时任务触发器中,然后
226  * 定时从触发器中提取到期的任务并触发
227  */
228 template <typename T>
229 class thread_trigger : public thread
230 {
231 public:
233  : delay_(100) // 初始化时的超时等待时间(毫秒)
234  , stop_(false) // 是否停止线程
235  {
236  }
237 
238  virtual ~thread_trigger(void) {}
239 
240  /**
241  * 添加一个定时任务对象
242  * @pararm o {T*}
243  */
244  void add(T* o)
245  {
246  mbox_.push(o);
247  }
248 
249  /**
250  * 添加要删除的定时任务对象到临时队列中,然后从定时器中删除之
251  * @pararm o {T*}
252  */
253  void del(T* o)
254  {
255  lock_.lock();
256  timer_del_.push_back(o);
257  lock_.unlock();
258  }
259 
261  {
262  return timer_;
263  }
264 
265 private:
266  // @override
267  void* run(void)
268  {
269  while (!stop_) {
270  T* o = mbox_.pop(delay_);
271  if (o)
272  timer_.add(o);
273 
274  long long next = timer_.trigger();
275  long long curr = get_curr_stamp();
276  if (next == -1)
277  delay_ = 100;
278  else {
279  delay_ = next - curr;
280  if (delay_ < 0)
281  delay_ = 1;
282  }
283 
284  lock_.lock();
285  typename std::vector<T*>::iterator it;
286  for (it = timer_del_.begin();
287  it != timer_del_.end(); ++it) {
288 
289  timer_.del(*it);
290  }
291  timer_del_.clear();
292  lock_.unlock();
293  }
294  return NULL;
295  }
296 
297 private:
298  long long delay_;
299  bool stop_;
300 
301  timer_trigger<T> timer_;
302  mbox<T> mbox_;
303 
304  std::vector<T*> timer_del_;
305  thread_mutex lock_;
306 };
307 
308 } // namespace acl
trigger_items_t::iterator trigger_iter_t
Definition: trigger.hpp:117
int del(T *o)
Definition: trigger.hpp:40
virtual ~thread_trigger(void)
Definition: trigger.hpp:238
std::map< long long, trigger_item< T > * > trigger_items_t
Definition: trigger.hpp:20
void del(T *o)
Definition: trigger.hpp:253
bool unlock(void)
long long trigger(void)
Definition: trigger.hpp:166
timer_trigger< T > & get_trigger(void)
Definition: trigger.hpp:260
trigger_item(trigger_items_t &items)
Definition: trigger.hpp:22
~trigger_item(void)
Definition: trigger.hpp:23
std::vector< T * > & get_objs(void)
Definition: trigger.hpp:57
std::map< long long, trigger_item< T > * > trigger_items_t
Definition: trigger.hpp:116
void add(T *o)
Definition: trigger.hpp:244
void add(T *o)
Definition: trigger.hpp:126
ACL_CPP_API long long get_curr_stamp(void)
void add(T *o)
Definition: trigger.hpp:29