170523619SShuo Chen // excerpts from http://code.google.com/p/muduo/
270523619SShuo Chen //
370523619SShuo Chen // Use of this source code is governed by a BSD-style license
470523619SShuo Chen // that can be found in the License file.
570523619SShuo Chen //
670523619SShuo Chen // Author: Shuo Chen (chenshuo at chenshuo dot com)
770523619SShuo Chen 
870523619SShuo Chen #ifndef MUDUO_NET_EVENTLOOP_H
970523619SShuo Chen #define MUDUO_NET_EVENTLOOP_H
1070523619SShuo Chen 
1170523619SShuo Chen #include "datetime/Timestamp.h"
1270523619SShuo Chen #include "thread/Mutex.h"
1370523619SShuo Chen #include "thread/Thread.h"
1470523619SShuo Chen #include "Callbacks.h"
1570523619SShuo Chen #include "TimerId.h"
1670523619SShuo Chen 
1770523619SShuo Chen #include <boost/scoped_ptr.hpp>
1870523619SShuo Chen #include <vector>
1970523619SShuo Chen 
2070523619SShuo Chen namespace muduo
2170523619SShuo Chen {
2270523619SShuo Chen 
2370523619SShuo Chen class Channel;
2470523619SShuo Chen-class Poller;
2570523619SShuo Chen+class EPoller;
2670523619SShuo Chen class TimerQueue;
2770523619SShuo Chen 
2870523619SShuo Chen class EventLoop : boost::noncopyable
2970523619SShuo Chen {
3070523619SShuo Chen  public:
3170523619SShuo Chen   typedef boost::function<void()> Functor;
3270523619SShuo Chen 
3370523619SShuo Chen   EventLoop();
3470523619SShuo Chen 
3570523619SShuo Chen   // force out-line dtor, for scoped_ptr members.
3670523619SShuo Chen   ~EventLoop();
3770523619SShuo Chen 
3870523619SShuo Chen   ///
3970523619SShuo Chen   /// Loops forever.
4070523619SShuo Chen   ///
4170523619SShuo Chen   /// Must be called in the same thread as creation of the object.
4270523619SShuo Chen   ///
4370523619SShuo Chen   void loop();
4470523619SShuo Chen 
4570523619SShuo Chen   void quit();
4670523619SShuo Chen 
4770523619SShuo Chen   ///
4870523619SShuo Chen   /// Time when poll returns, usually means data arrivial.
4970523619SShuo Chen   ///
5070523619SShuo Chen   Timestamp pollReturnTime() const { return pollReturnTime_; }
5170523619SShuo Chen 
5270523619SShuo Chen   /// Runs callback immediately in the loop thread.
5370523619SShuo Chen   /// It wakes up the loop, and run the cb.
5470523619SShuo Chen   /// If in the same loop thread, cb is run within the function.
5570523619SShuo Chen   /// Safe to call from other threads.
5670523619SShuo Chen   void runInLoop(const Functor& cb);
5770523619SShuo Chen   /// Queues callback in the loop thread.
5870523619SShuo Chen   /// Runs after finish pooling.
5970523619SShuo Chen   /// Safe to call from other threads.
6070523619SShuo Chen   void queueInLoop(const Functor& cb);
6170523619SShuo Chen 
6270523619SShuo Chen   // timers
6370523619SShuo Chen 
6470523619SShuo Chen   ///
6570523619SShuo Chen   /// Runs callback at 'time'.
6670523619SShuo Chen   /// Safe to call from other threads.
6770523619SShuo Chen   ///
6870523619SShuo Chen   TimerId runAt(const Timestamp& time, const TimerCallback& cb);
6970523619SShuo Chen   ///
7070523619SShuo Chen   /// Runs callback after @c delay seconds.
7170523619SShuo Chen   /// Safe to call from other threads.
7270523619SShuo Chen   ///
7370523619SShuo Chen   TimerId runAfter(double delay, const TimerCallback& cb);
7470523619SShuo Chen   ///
7570523619SShuo Chen   /// Runs callback every @c interval seconds.
7670523619SShuo Chen   /// Safe to call from other threads.
7770523619SShuo Chen   ///
7870523619SShuo Chen   TimerId runEvery(double interval, const TimerCallback& cb);
7970523619SShuo Chen 
8070523619SShuo Chen   void cancel(TimerId timerId);
8170523619SShuo Chen 
8270523619SShuo Chen   // internal use only
8370523619SShuo Chen   void wakeup();
8470523619SShuo Chen   void updateChannel(Channel* channel);
8570523619SShuo Chen   void removeChannel(Channel* channel);
8670523619SShuo Chen 
8770523619SShuo Chen   void assertInLoopThread()
8870523619SShuo Chen   {
8970523619SShuo Chen     if (!isInLoopThread())
9070523619SShuo Chen     {
9170523619SShuo Chen       abortNotInLoopThread();
9270523619SShuo Chen     }
9370523619SShuo Chen   }
9470523619SShuo Chen 
9570523619SShuo Chen   bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
9670523619SShuo Chen 
9770523619SShuo Chen  private:
9870523619SShuo Chen 
9970523619SShuo Chen   void abortNotInLoopThread();
10070523619SShuo Chen   void handleRead();  // waked up
10170523619SShuo Chen   void doPendingFunctors();
10270523619SShuo Chen 
10370523619SShuo Chen   typedef std::vector<Channel*> ChannelList;
10470523619SShuo Chen 
10570523619SShuo Chen   bool looping_; /* atomic */
10670523619SShuo Chen   bool quit_; /* atomic */
10770523619SShuo Chen   bool callingPendingFunctors_; /* atomic */
10870523619SShuo Chen   const pid_t threadId_;
10970523619SShuo Chen   Timestamp pollReturnTime_;
11070523619SShuo Chen-  boost::scoped_ptr<Poller> poller_;
11170523619SShuo Chen+  boost::scoped_ptr<EPoller> poller_;
11270523619SShuo Chen   boost::scoped_ptr<TimerQueue> timerQueue_;
11370523619SShuo Chen   int wakeupFd_;
11470523619SShuo Chen   // unlike in TimerQueue, which is an internal class,
11570523619SShuo Chen   // we don't expose Channel to client.
11670523619SShuo Chen   boost::scoped_ptr<Channel> wakeupChannel_;
11770523619SShuo Chen   ChannelList activeChannels_;
11870523619SShuo Chen   MutexLock mutex_;
11970523619SShuo Chen   std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_
12070523619SShuo Chen };
12170523619SShuo Chen 
12270523619SShuo Chen }
12370523619SShuo Chen 
12470523619SShuo Chen #endif  // MUDUO_NET_EVENTLOOP_H
125