1048f6023SShuo Chen // excerpts from http://code.google.com/p/muduo/ 2048f6023SShuo Chen // 3048f6023SShuo Chen // Use of this source code is governed by a BSD-style license 4048f6023SShuo Chen // that can be found in the License file. 5048f6023SShuo Chen // 6048f6023SShuo Chen // Author: Shuo Chen (chenshuo at chenshuo dot com) 7048f6023SShuo Chen 8048f6023SShuo Chen #ifndef MUDUO_NET_EVENTLOOP_H 9048f6023SShuo Chen #define MUDUO_NET_EVENTLOOP_H 10048f6023SShuo Chen 11048f6023SShuo Chen #include "datetime/Timestamp.h" 12048f6023SShuo Chen #include "thread/Mutex.h" 13048f6023SShuo Chen #include "thread/Thread.h" 14048f6023SShuo Chen #include "Callbacks.h" 15048f6023SShuo Chen #include "TimerId.h" 16048f6023SShuo Chen 17048f6023SShuo Chen #include <boost/scoped_ptr.hpp> 18048f6023SShuo Chen #include <vector> 19048f6023SShuo Chen 20048f6023SShuo Chen namespace muduo 21048f6023SShuo Chen { 22048f6023SShuo Chen 23048f6023SShuo Chen class Channel; 24048f6023SShuo Chen class Poller; 25048f6023SShuo Chen class TimerQueue; 26048f6023SShuo Chen 27048f6023SShuo Chen class EventLoop : boost::noncopyable 28048f6023SShuo Chen { 29048f6023SShuo Chen public: 30048f6023SShuo Chen typedef boost::function<void()> Functor; 31048f6023SShuo Chen 32048f6023SShuo Chen EventLoop(); 33048f6023SShuo Chen 34048f6023SShuo Chen // force out-line dtor, for scoped_ptr members. 35048f6023SShuo Chen ~EventLoop(); 36048f6023SShuo Chen 37048f6023SShuo Chen /// 38048f6023SShuo Chen /// Loops forever. 39048f6023SShuo Chen /// 40048f6023SShuo Chen /// Must be called in the same thread as creation of the object. 41048f6023SShuo Chen /// 42048f6023SShuo Chen void loop(); 43048f6023SShuo Chen 44048f6023SShuo Chen void quit(); 45048f6023SShuo Chen 46048f6023SShuo Chen /// 47048f6023SShuo Chen /// Time when poll returns, usually means data arrivial. 48048f6023SShuo Chen /// 49048f6023SShuo Chen Timestamp pollReturnTime() const { return pollReturnTime_; } 50048f6023SShuo Chen 51048f6023SShuo Chen /// Runs callback immediately in the loop thread. 52048f6023SShuo Chen /// It wakes up the loop, and run the cb. 53048f6023SShuo Chen /// If in the same loop thread, cb is run within the function. 54048f6023SShuo Chen /// Safe to call from other threads. 55048f6023SShuo Chen void runInLoop(const Functor& cb); 56048f6023SShuo Chen /// Queues callback in the loop thread. 57048f6023SShuo Chen /// Runs after finish pooling. 58048f6023SShuo Chen /// Safe to call from other threads. 59048f6023SShuo Chen void queueInLoop(const Functor& cb); 60048f6023SShuo Chen 61048f6023SShuo Chen // timers 62048f6023SShuo Chen 63048f6023SShuo Chen /// 64048f6023SShuo Chen /// Runs callback at 'time'. 65048f6023SShuo Chen /// Safe to call from other threads. 66048f6023SShuo Chen /// 67048f6023SShuo Chen TimerId runAt(const Timestamp& time, const TimerCallback& cb); 68048f6023SShuo Chen /// 69048f6023SShuo Chen /// Runs callback after @c delay seconds. 70048f6023SShuo Chen /// Safe to call from other threads. 71048f6023SShuo Chen /// 72048f6023SShuo Chen TimerId runAfter(double delay, const TimerCallback& cb); 73048f6023SShuo Chen /// 74048f6023SShuo Chen /// Runs callback every @c interval seconds. 75048f6023SShuo Chen /// Safe to call from other threads. 76048f6023SShuo Chen /// 77048f6023SShuo Chen TimerId runEvery(double interval, const TimerCallback& cb); 78048f6023SShuo Chen 79048f6023SShuo Chen // void cancel(TimerId timerId); 80048f6023SShuo Chen 81048f6023SShuo Chen // internal use only 82048f6023SShuo Chen void wakeup(); 83048f6023SShuo Chen void updateChannel(Channel* channel); 84048f6023SShuo Chen! void removeChannel(Channel* channel); 85048f6023SShuo Chen 86048f6023SShuo Chen void assertInLoopThread() 87048f6023SShuo Chen { 88048f6023SShuo Chen if (!isInLoopThread()) 89048f6023SShuo Chen { 90048f6023SShuo Chen abortNotInLoopThread(); 91048f6023SShuo Chen } 92048f6023SShuo Chen } 93048f6023SShuo Chen 94048f6023SShuo Chen bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); } 95048f6023SShuo Chen 96048f6023SShuo Chen private: 97048f6023SShuo Chen 98048f6023SShuo Chen void abortNotInLoopThread(); 99048f6023SShuo Chen void handleRead(); // waked up 100048f6023SShuo Chen void doPendingFunctors(); 101048f6023SShuo Chen 102048f6023SShuo Chen typedef std::vector<Channel*> ChannelList; 103048f6023SShuo Chen 104048f6023SShuo Chen bool looping_; /* atomic */ 105048f6023SShuo Chen bool quit_; /* atomic */ 106048f6023SShuo Chen bool callingPendingFunctors_; /* atomic */ 107048f6023SShuo Chen const pid_t threadId_; 108048f6023SShuo Chen Timestamp pollReturnTime_; 109048f6023SShuo Chen boost::scoped_ptr<Poller> poller_; 110048f6023SShuo Chen boost::scoped_ptr<TimerQueue> timerQueue_; 111048f6023SShuo Chen int wakeupFd_; 112048f6023SShuo Chen // unlike in TimerQueue, which is an internal class, 113048f6023SShuo Chen // we don't expose Channel to client. 114048f6023SShuo Chen boost::scoped_ptr<Channel> wakeupChannel_; 115048f6023SShuo Chen ChannelList activeChannels_; 116048f6023SShuo Chen MutexLock mutex_; 117fd65b0afSShuo Chen std::vector<Functor> pendingFunctors_; // @GuardedBy mutex_ 118048f6023SShuo Chen }; 119048f6023SShuo Chen 120048f6023SShuo Chen } 121048f6023SShuo Chen 122048f6023SShuo Chen #endif // MUDUO_NET_EVENTLOOP_H 123