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