s03-s02-EventLoop.h.diff revision 048f6023
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 TimerQueue;
26 
27 class 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_; // @BuardedBy mutex_
118 };
119 
120 }
121 
122 #endif  // MUDUO_NET_EVENTLOOP_H
123