140161064SShuo Chen// excerpts from http://code.google.com/p/muduo/
240161064SShuo Chen//
340161064SShuo Chen// Use of this source code is governed by a BSD-style license
440161064SShuo Chen// that can be found in the License file.
540161064SShuo Chen//
640161064SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
740161064SShuo Chen
840161064SShuo Chen#ifndef MUDUO_NET_TIMERQUEUE_H
940161064SShuo Chen#define MUDUO_NET_TIMERQUEUE_H
1040161064SShuo Chen
1140161064SShuo Chen#include <set>
1240161064SShuo Chen#include <vector>
1340161064SShuo Chen
1440161064SShuo Chen#include <boost/noncopyable.hpp>
1540161064SShuo Chen
1640161064SShuo Chen#include "datetime/Timestamp.h"
1740161064SShuo Chen#include "thread/Mutex.h"
1840161064SShuo Chen#include "Callbacks.h"
1940161064SShuo Chen#include "Channel.h"
2040161064SShuo Chen
2140161064SShuo Chennamespace muduo
2240161064SShuo Chen{
2340161064SShuo Chen
2440161064SShuo Chenclass EventLoop;
2540161064SShuo Chenclass Timer;
2640161064SShuo Chenclass TimerId;
2740161064SShuo Chen
2840161064SShuo Chen///
2940161064SShuo Chen/// A best efforts timer queue.
3040161064SShuo Chen/// No guarantee that the callback will be on time.
3140161064SShuo Chen///
3240161064SShuo Chenclass TimerQueue : boost::noncopyable
3340161064SShuo Chen{
3440161064SShuo Chen public:
3540161064SShuo Chen  TimerQueue(EventLoop* loop);
3640161064SShuo Chen  ~TimerQueue();
3740161064SShuo Chen
3840161064SShuo Chen  ///
3940161064SShuo Chen  /// Schedules the callback to be run at given time,
4040161064SShuo Chen  /// repeats if @c interval > 0.0.
4140161064SShuo Chen  ///
4240161064SShuo Chen  /// Must be thread safe. Usually be called from other threads.
4340161064SShuo Chen  TimerId addTimer(const TimerCallback& cb,
4440161064SShuo Chen                   Timestamp when,
4540161064SShuo Chen                   double interval);
4640161064SShuo Chen
47f4e8e3d3SShuo Chen  void cancel(TimerId timerId);
4840161064SShuo Chen
4940161064SShuo Chen private:
5040161064SShuo Chen
5140161064SShuo Chen  // FIXME: use unique_ptr<Timer> instead of raw pointers.
5240161064SShuo Chen  typedef std::pair<Timestamp, Timer*> Entry;
5340161064SShuo Chen  typedef std::set<Entry> TimerList;
54f4e8e3d3SShuo Chen  typedef std::pair<Timer*, int64_t> ActiveTimer;
55f4e8e3d3SShuo Chen  typedef std::set<ActiveTimer> ActiveTimerSet;
5640161064SShuo Chen
57f4e8e3d3SShuo Chen  void addTimerInLoop(Timer* timer);
58f4e8e3d3SShuo Chen  void cancelInLoop(TimerId timerId);
5940161064SShuo Chen  // called when timerfd alarms
6040161064SShuo Chen  void handleRead();
6140161064SShuo Chen  // move out all expired timers
6240161064SShuo Chen  std::vector<Entry> getExpired(Timestamp now);
6340161064SShuo Chen  void reset(const std::vector<Entry>& expired, Timestamp now);
6440161064SShuo Chen
6540161064SShuo Chen  bool insert(Timer* timer);
6640161064SShuo Chen
6740161064SShuo Chen  EventLoop* loop_;
6840161064SShuo Chen  const int timerfd_;
6940161064SShuo Chen  Channel timerfdChannel_;
7040161064SShuo Chen  // Timer list sorted by expiration
7140161064SShuo Chen  TimerList timers_;
72f4e8e3d3SShuo Chen
73f4e8e3d3SShuo Chen  // for cancel()
74f4e8e3d3SShuo Chen  bool callingExpiredTimers_; /* atomic */
75f4e8e3d3SShuo Chen  ActiveTimerSet activeTimers_;
76f4e8e3d3SShuo Chen  ActiveTimerSet cancelingTimers_;
7740161064SShuo Chen};
7840161064SShuo Chen
7940161064SShuo Chen}
8040161064SShuo Chen#endif  // MUDUO_NET_TIMERQUEUE_H
81