EventLoop.h revision 17c057c3
1bfe73648SShuo Chen// excerpts from http://code.google.com/p/muduo/
2bfe73648SShuo Chen//
3bfe73648SShuo Chen// Use of this source code is governed by a BSD-style license
4bfe73648SShuo Chen// that can be found in the License file.
5bfe73648SShuo Chen//
6bfe73648SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
7bfe73648SShuo Chen
8bfe73648SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H
9bfe73648SShuo Chen#define MUDUO_NET_EVENTLOOP_H
10bfe73648SShuo Chen
11bfe73648SShuo Chen#include "datetime/Timestamp.h"
12bfe73648SShuo Chen#include "thread/Mutex.h"
13bfe73648SShuo Chen#include "thread/Thread.h"
14bfe73648SShuo Chen#include "Callbacks.h"
15bfe73648SShuo Chen#include "TimerId.h"
16bfe73648SShuo Chen
17bfe73648SShuo Chen#include <boost/scoped_ptr.hpp>
18bfe73648SShuo Chen#include <vector>
19bfe73648SShuo Chen
20bfe73648SShuo Chennamespace muduo
21bfe73648SShuo Chen{
22bfe73648SShuo Chen
23bfe73648SShuo Chenclass Channel;
24bfe73648SShuo Chenclass Poller;
25bfe73648SShuo Chenclass TimerQueue;
26bfe73648SShuo Chen
27bfe73648SShuo Chenclass EventLoop : boost::noncopyable
28bfe73648SShuo Chen{
29bfe73648SShuo Chen public:
30bfe73648SShuo Chen  typedef boost::function<void()> Functor;
31bfe73648SShuo Chen
32bfe73648SShuo Chen  EventLoop();
33bfe73648SShuo Chen
34bfe73648SShuo Chen  // force out-line dtor, for scoped_ptr members.
35bfe73648SShuo Chen  ~EventLoop();
36bfe73648SShuo Chen
37bfe73648SShuo Chen  ///
38bfe73648SShuo Chen  /// Loops forever.
39bfe73648SShuo Chen  ///
40bfe73648SShuo Chen  /// Must be called in the same thread as creation of the object.
41bfe73648SShuo Chen  ///
42bfe73648SShuo Chen  void loop();
43bfe73648SShuo Chen
44bfe73648SShuo Chen  void quit();
45bfe73648SShuo Chen
46bfe73648SShuo Chen  ///
47bfe73648SShuo Chen  /// Time when poll returns, usually means data arrivial.
48bfe73648SShuo Chen  ///
49bfe73648SShuo Chen  Timestamp pollReturnTime() const { return pollReturnTime_; }
50bfe73648SShuo Chen
51bfe73648SShuo Chen  /// Runs callback immediately in the loop thread.
52bfe73648SShuo Chen  /// It wakes up the loop, and run the cb.
53bfe73648SShuo Chen  /// If in the same loop thread, cb is run within the function.
54bfe73648SShuo Chen  /// Safe to call from other threads.
55bfe73648SShuo Chen  void runInLoop(const Functor& cb);
56bfe73648SShuo Chen  /// Queues callback in the loop thread.
57bfe73648SShuo Chen  /// Runs after finish pooling.
58bfe73648SShuo Chen  /// Safe to call from other threads.
59bfe73648SShuo Chen  void queueInLoop(const Functor& cb);
60bfe73648SShuo Chen
61bfe73648SShuo Chen  // timers
62bfe73648SShuo Chen
63bfe73648SShuo Chen  ///
64bfe73648SShuo Chen  /// Runs callback at 'time'.
65bfe73648SShuo Chen  /// Safe to call from other threads.
66bfe73648SShuo Chen  ///
67bfe73648SShuo Chen  TimerId runAt(const Timestamp& time, const TimerCallback& cb);
68bfe73648SShuo Chen  ///
69bfe73648SShuo Chen  /// Runs callback after @c delay seconds.
70bfe73648SShuo Chen  /// Safe to call from other threads.
71bfe73648SShuo Chen  ///
72bfe73648SShuo Chen  TimerId runAfter(double delay, const TimerCallback& cb);
73bfe73648SShuo Chen  ///
74bfe73648SShuo Chen  /// Runs callback every @c interval seconds.
75bfe73648SShuo Chen  /// Safe to call from other threads.
76bfe73648SShuo Chen  ///
77bfe73648SShuo Chen  TimerId runEvery(double interval, const TimerCallback& cb);
78bfe73648SShuo Chen
79bfe73648SShuo Chen  // void cancel(TimerId timerId);
80bfe73648SShuo Chen
81bfe73648SShuo Chen  // internal use only
82bfe73648SShuo Chen  void wakeup();
83bfe73648SShuo Chen  void updateChannel(Channel* channel);
8417c057c3SShuo Chen  void removeChannel(Channel* channel);
85bfe73648SShuo Chen
86bfe73648SShuo Chen  void assertInLoopThread()
87bfe73648SShuo Chen  {
88bfe73648SShuo Chen    if (!isInLoopThread())
89bfe73648SShuo Chen    {
90bfe73648SShuo Chen      abortNotInLoopThread();
91bfe73648SShuo Chen    }
92bfe73648SShuo Chen  }
93bfe73648SShuo Chen
94bfe73648SShuo Chen  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
95bfe73648SShuo Chen
96bfe73648SShuo Chen private:
97bfe73648SShuo Chen
98bfe73648SShuo Chen  void abortNotInLoopThread();
99bfe73648SShuo Chen  void handleRead();  // waked up
100bfe73648SShuo Chen  void doPendingFunctors();
101bfe73648SShuo Chen
102bfe73648SShuo Chen  typedef std::vector<Channel*> ChannelList;
103bfe73648SShuo Chen
104bfe73648SShuo Chen  bool looping_; /* atomic */
105bfe73648SShuo Chen  bool quit_; /* atomic */
106bfe73648SShuo Chen  bool callingPendingFunctors_; /* atomic */
107bfe73648SShuo Chen  const pid_t threadId_;
108bfe73648SShuo Chen  Timestamp pollReturnTime_;
109bfe73648SShuo Chen  boost::scoped_ptr<Poller> poller_;
110bfe73648SShuo Chen  boost::scoped_ptr<TimerQueue> timerQueue_;
111bfe73648SShuo Chen  int wakeupFd_;
112bfe73648SShuo Chen  // unlike in TimerQueue, which is an internal class,
113bfe73648SShuo Chen  // we don't expose Channel to client.
114bfe73648SShuo Chen  boost::scoped_ptr<Channel> wakeupChannel_;
115bfe73648SShuo Chen  ChannelList activeChannels_;
116bfe73648SShuo Chen  MutexLock mutex_;
117bfe73648SShuo Chen  std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_
118bfe73648SShuo Chen};
119bfe73648SShuo Chen
120bfe73648SShuo Chen}
121bfe73648SShuo Chen
122bfe73648SShuo Chen#endif  // MUDUO_NET_EVENTLOOP_H
123