1354280cfSShuo Chen// excerpts from http://code.google.com/p/muduo/
2354280cfSShuo Chen//
3354280cfSShuo Chen// Use of this source code is governed by a BSD-style license
4354280cfSShuo Chen// that can be found in the License file.
5354280cfSShuo Chen//
6354280cfSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
7354280cfSShuo Chen
8354280cfSShuo Chen#ifndef MUDUO_NET_TIMERQUEUE_H
9354280cfSShuo Chen#define MUDUO_NET_TIMERQUEUE_H
10354280cfSShuo Chen
11354280cfSShuo Chen#include <set>
12354280cfSShuo Chen#include <vector>
13354280cfSShuo Chen
14354280cfSShuo Chen#include <boost/noncopyable.hpp>
15354280cfSShuo Chen
16354280cfSShuo Chen#include "datetime/Timestamp.h"
17354280cfSShuo Chen#include "thread/Mutex.h"
18354280cfSShuo Chen#include "Callbacks.h"
19354280cfSShuo Chen#include "Channel.h"
20354280cfSShuo Chen
21354280cfSShuo Chennamespace muduo
22354280cfSShuo Chen{
23354280cfSShuo Chen
24354280cfSShuo Chenclass EventLoop;
25354280cfSShuo Chenclass Timer;
26354280cfSShuo Chenclass TimerId;
27354280cfSShuo Chen
28354280cfSShuo Chen///
29354280cfSShuo Chen/// A best efforts timer queue.
30354280cfSShuo Chen/// No guarantee that the callback will be on time.
31354280cfSShuo Chen///
32354280cfSShuo Chenclass TimerQueue : boost::noncopyable
33354280cfSShuo Chen{
34354280cfSShuo Chen public:
35354280cfSShuo Chen  TimerQueue(EventLoop* loop);
36354280cfSShuo Chen  ~TimerQueue();
37354280cfSShuo Chen
38354280cfSShuo Chen  ///
39354280cfSShuo Chen  /// Schedules the callback to be run at given time,
40354280cfSShuo Chen  /// repeats if @c interval > 0.0.
41354280cfSShuo Chen  ///
42354280cfSShuo Chen  /// Must be thread safe. Usually be called from other threads.
43354280cfSShuo Chen  TimerId addTimer(const TimerCallback& cb,
44354280cfSShuo Chen                   Timestamp when,
45354280cfSShuo Chen                   double interval);
46354280cfSShuo Chen
47354280cfSShuo Chen  void cancel(TimerId timerId);
48354280cfSShuo Chen
49354280cfSShuo Chen private:
50354280cfSShuo Chen
51354280cfSShuo Chen  // FIXME: use unique_ptr<Timer> instead of raw pointers.
52354280cfSShuo Chen  typedef std::pair<Timestamp, Timer*> Entry;
53354280cfSShuo Chen  typedef std::set<Entry> TimerList;
54354280cfSShuo Chen  typedef std::pair<Timer*, int64_t> ActiveTimer;
55354280cfSShuo Chen  typedef std::set<ActiveTimer> ActiveTimerSet;
56354280cfSShuo Chen
57354280cfSShuo Chen  void addTimerInLoop(Timer* timer);
58354280cfSShuo Chen  void cancelInLoop(TimerId timerId);
59354280cfSShuo Chen  // called when timerfd alarms
60354280cfSShuo Chen  void handleRead();
61354280cfSShuo Chen  // move out all expired timers
62354280cfSShuo Chen  std::vector<Entry> getExpired(Timestamp now);
63354280cfSShuo Chen  void reset(const std::vector<Entry>& expired, Timestamp now);
64354280cfSShuo Chen
65354280cfSShuo Chen  bool insert(Timer* timer);
66354280cfSShuo Chen
67354280cfSShuo Chen  EventLoop* loop_;
68354280cfSShuo Chen  const int timerfd_;
69354280cfSShuo Chen  Channel timerfdChannel_;
70354280cfSShuo Chen  // Timer list sorted by expiration
71354280cfSShuo Chen  TimerList timers_;
72354280cfSShuo Chen
73354280cfSShuo Chen  // for cancel()
74354280cfSShuo Chen  bool callingExpiredTimers_; /* atomic */
75354280cfSShuo Chen  ActiveTimerSet activeTimers_;
76354280cfSShuo Chen  ActiveTimerSet cancelingTimers_;
77354280cfSShuo Chen};
78354280cfSShuo Chen
79354280cfSShuo Chen}
80354280cfSShuo Chen#endif  // MUDUO_NET_TIMERQUEUE_H
81