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