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