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