1 // excerpts from http://code.google.com/p/muduo/
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the License file.
5 //
6 // Author: Shuo Chen (chenshuo at chenshuo dot com)
7 
8 #ifndef MUDUO_NET_TIMERQUEUE_H
9 #define MUDUO_NET_TIMERQUEUE_H
10 
11 #include <set>
12 #include <vector>
13 
14 #include <boost/noncopyable.hpp>
15 
16 #include "datetime/Timestamp.h"
17 #include "thread/Mutex.h"
18 #include "Callbacks.h"
19 #include "Channel.h"
20 
21 namespace muduo
22 {
23 
24 class EventLoop;
25 class Timer;
26 class TimerId;
27 
28 ///
29 /// A best efforts timer queue.
30 /// No guarantee that the callback will be on time.
31 ///
32 class TimerQueue : boost::noncopyable
33 {
34  public:
35   TimerQueue(EventLoop* loop);
36   ~TimerQueue();
37 
38   ///
39   /// Schedules the callback to be run at given time,
40   /// repeats if @c interval > 0.0.
41   ///
42   /// Must be thread safe. Usually be called from other threads.
43   TimerId addTimer(const TimerCallback& cb,
44                    Timestamp when,
45                    double interval);
46 
47+  void cancel(TimerId timerId);
48 
49  private:
50 
51   // FIXME: use unique_ptr<Timer> instead of raw pointers.
52   typedef std::pair<Timestamp, Timer*> Entry;
53   typedef std::set<Entry> TimerList;
54+  typedef std::pair<Timer*, int64_t> ActiveTimer;
55+  typedef std::set<ActiveTimer> ActiveTimerSet;
56 
57   void addTimerInLoop(Timer* timer);
58+  void cancelInLoop(TimerId timerId);
59   // called when timerfd alarms
60   void handleRead();
61   // move out all expired timers
62   std::vector<Entry> getExpired(Timestamp now);
63   void reset(const std::vector<Entry>& expired, Timestamp now);
64 
65   bool insert(Timer* timer);
66 
67   EventLoop* loop_;
68   const int timerfd_;
69   Channel timerfdChannel_;
70   // Timer list sorted by expiration
71   TimerList timers_;
72+
73+  // for cancel()
74+  bool callingExpiredTimers_; /* atomic */
75+  ActiveTimerSet activeTimers_;
76+  ActiveTimerSet cancelingTimers_;
77 };
78 
79 }
80 #endif  // MUDUO_NET_TIMERQUEUE_H
81