EventLoop.h revision bfe73648
1bfe73648SShuo Chen// excerpts from http://code.google.com/p/muduo/ 2bfe73648SShuo Chen// 3bfe73648SShuo Chen// Use of this source code is governed by a BSD-style license 4bfe73648SShuo Chen// that can be found in the License file. 5bfe73648SShuo Chen// 6bfe73648SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 7bfe73648SShuo Chen 8bfe73648SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H 9bfe73648SShuo Chen#define MUDUO_NET_EVENTLOOP_H 10bfe73648SShuo Chen 11bfe73648SShuo Chen#include "datetime/Timestamp.h" 12bfe73648SShuo Chen#include "thread/Mutex.h" 13bfe73648SShuo Chen#include "thread/Thread.h" 14bfe73648SShuo Chen#include "Callbacks.h" 15bfe73648SShuo Chen#include "TimerId.h" 16bfe73648SShuo Chen 17bfe73648SShuo Chen#include <boost/scoped_ptr.hpp> 18bfe73648SShuo Chen#include <vector> 19bfe73648SShuo Chen 20bfe73648SShuo Chennamespace muduo 21bfe73648SShuo Chen{ 22bfe73648SShuo Chen 23bfe73648SShuo Chenclass Channel; 24bfe73648SShuo Chenclass Poller; 25bfe73648SShuo Chenclass TimerQueue; 26bfe73648SShuo Chen 27bfe73648SShuo Chenclass EventLoop : boost::noncopyable 28bfe73648SShuo Chen{ 29bfe73648SShuo Chen public: 30bfe73648SShuo Chen typedef boost::function<void()> Functor; 31bfe73648SShuo Chen 32bfe73648SShuo Chen EventLoop(); 33bfe73648SShuo Chen 34bfe73648SShuo Chen // force out-line dtor, for scoped_ptr members. 35bfe73648SShuo Chen ~EventLoop(); 36bfe73648SShuo Chen 37bfe73648SShuo Chen /// 38bfe73648SShuo Chen /// Loops forever. 39bfe73648SShuo Chen /// 40bfe73648SShuo Chen /// Must be called in the same thread as creation of the object. 41bfe73648SShuo Chen /// 42bfe73648SShuo Chen void loop(); 43bfe73648SShuo Chen 44bfe73648SShuo Chen void quit(); 45bfe73648SShuo Chen 46bfe73648SShuo Chen /// 47bfe73648SShuo Chen /// Time when poll returns, usually means data arrivial. 48bfe73648SShuo Chen /// 49bfe73648SShuo Chen Timestamp pollReturnTime() const { return pollReturnTime_; } 50bfe73648SShuo Chen 51bfe73648SShuo Chen /// Runs callback immediately in the loop thread. 52bfe73648SShuo Chen /// It wakes up the loop, and run the cb. 53bfe73648SShuo Chen /// If in the same loop thread, cb is run within the function. 54bfe73648SShuo Chen /// Safe to call from other threads. 55bfe73648SShuo Chen void runInLoop(const Functor& cb); 56bfe73648SShuo Chen /// Queues callback in the loop thread. 57bfe73648SShuo Chen /// Runs after finish pooling. 58bfe73648SShuo Chen /// Safe to call from other threads. 59bfe73648SShuo Chen void queueInLoop(const Functor& cb); 60bfe73648SShuo Chen 61bfe73648SShuo Chen // timers 62bfe73648SShuo Chen 63bfe73648SShuo Chen /// 64bfe73648SShuo Chen /// Runs callback at 'time'. 65bfe73648SShuo Chen /// Safe to call from other threads. 66bfe73648SShuo Chen /// 67bfe73648SShuo Chen TimerId runAt(const Timestamp& time, const TimerCallback& cb); 68bfe73648SShuo Chen /// 69bfe73648SShuo Chen /// Runs callback after @c delay seconds. 70bfe73648SShuo Chen /// Safe to call from other threads. 71bfe73648SShuo Chen /// 72bfe73648SShuo Chen TimerId runAfter(double delay, const TimerCallback& cb); 73bfe73648SShuo Chen /// 74bfe73648SShuo Chen /// Runs callback every @c interval seconds. 75bfe73648SShuo Chen /// Safe to call from other threads. 76bfe73648SShuo Chen /// 77bfe73648SShuo Chen TimerId runEvery(double interval, const TimerCallback& cb); 78bfe73648SShuo Chen 79bfe73648SShuo Chen // void cancel(TimerId timerId); 80bfe73648SShuo Chen 81bfe73648SShuo Chen // internal use only 82bfe73648SShuo Chen void wakeup(); 83bfe73648SShuo Chen void updateChannel(Channel* channel); 84bfe73648SShuo Chen // void removeChannel(Channel* channel); 85bfe73648SShuo Chen 86bfe73648SShuo Chen void assertInLoopThread() 87bfe73648SShuo Chen { 88bfe73648SShuo Chen if (!isInLoopThread()) 89bfe73648SShuo Chen { 90bfe73648SShuo Chen abortNotInLoopThread(); 91bfe73648SShuo Chen } 92bfe73648SShuo Chen } 93bfe73648SShuo Chen 94bfe73648SShuo Chen bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); } 95bfe73648SShuo Chen 96bfe73648SShuo Chen private: 97bfe73648SShuo Chen 98bfe73648SShuo Chen void abortNotInLoopThread(); 99bfe73648SShuo Chen void handleRead(); // waked up 100bfe73648SShuo Chen void doPendingFunctors(); 101bfe73648SShuo Chen 102bfe73648SShuo Chen typedef std::vector<Channel*> ChannelList; 103bfe73648SShuo Chen 104bfe73648SShuo Chen bool looping_; /* atomic */ 105bfe73648SShuo Chen bool quit_; /* atomic */ 106bfe73648SShuo Chen bool callingPendingFunctors_; /* atomic */ 107bfe73648SShuo Chen const pid_t threadId_; 108bfe73648SShuo Chen Timestamp pollReturnTime_; 109bfe73648SShuo Chen boost::scoped_ptr<Poller> poller_; 110bfe73648SShuo Chen boost::scoped_ptr<TimerQueue> timerQueue_; 111bfe73648SShuo Chen int wakeupFd_; 112bfe73648SShuo Chen // unlike in TimerQueue, which is an internal class, 113bfe73648SShuo Chen // we don't expose Channel to client. 114bfe73648SShuo Chen boost::scoped_ptr<Channel> wakeupChannel_; 115bfe73648SShuo Chen ChannelList activeChannels_; 116bfe73648SShuo Chen MutexLock mutex_; 117bfe73648SShuo Chen std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_ 118bfe73648SShuo Chen 119bfe73648SShuo Chen}; 120bfe73648SShuo Chen 121bfe73648SShuo Chen} 122bfe73648SShuo Chen 123bfe73648SShuo Chen#endif // MUDUO_NET_EVENTLOOP_H 124