1354280cfSShuo Chen// excerpts from http://code.google.com/p/muduo/ 2354280cfSShuo Chen// 3354280cfSShuo Chen// Use of this source code is governed by a BSD-style license 4354280cfSShuo Chen// that can be found in the License file. 5354280cfSShuo Chen// 6354280cfSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 7354280cfSShuo Chen 8354280cfSShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H 9354280cfSShuo Chen#define MUDUO_NET_EVENTLOOP_H 10354280cfSShuo Chen 11354280cfSShuo Chen#include "datetime/Timestamp.h" 12354280cfSShuo Chen#include "thread/Mutex.h" 13354280cfSShuo Chen#include "thread/Thread.h" 14354280cfSShuo Chen#include "Callbacks.h" 15354280cfSShuo Chen#include "TimerId.h" 16354280cfSShuo Chen 17354280cfSShuo Chen#include <boost/scoped_ptr.hpp> 18354280cfSShuo Chen#include <vector> 19354280cfSShuo Chen 20354280cfSShuo Chennamespace muduo 21354280cfSShuo Chen{ 22354280cfSShuo Chen 23354280cfSShuo Chenclass Channel; 2470523619SShuo Chenclass EPoller; 25354280cfSShuo Chenclass TimerQueue; 26354280cfSShuo Chen 27354280cfSShuo Chenclass EventLoop : boost::noncopyable 28354280cfSShuo Chen{ 29354280cfSShuo Chen public: 30354280cfSShuo Chen typedef boost::function<void()> Functor; 31354280cfSShuo Chen 32354280cfSShuo Chen EventLoop(); 33354280cfSShuo Chen 34354280cfSShuo Chen // force out-line dtor, for scoped_ptr members. 35354280cfSShuo Chen ~EventLoop(); 36354280cfSShuo Chen 37354280cfSShuo Chen /// 38354280cfSShuo Chen /// Loops forever. 39354280cfSShuo Chen /// 40354280cfSShuo Chen /// Must be called in the same thread as creation of the object. 41354280cfSShuo Chen /// 42354280cfSShuo Chen void loop(); 43354280cfSShuo Chen 44354280cfSShuo Chen void quit(); 45354280cfSShuo Chen 46354280cfSShuo Chen /// 47354280cfSShuo Chen /// Time when poll returns, usually means data arrivial. 48354280cfSShuo Chen /// 49354280cfSShuo Chen Timestamp pollReturnTime() const { return pollReturnTime_; } 50354280cfSShuo Chen 51354280cfSShuo Chen /// Runs callback immediately in the loop thread. 52354280cfSShuo Chen /// It wakes up the loop, and run the cb. 53354280cfSShuo Chen /// If in the same loop thread, cb is run within the function. 54354280cfSShuo Chen /// Safe to call from other threads. 55354280cfSShuo Chen void runInLoop(const Functor& cb); 56354280cfSShuo Chen /// Queues callback in the loop thread. 57354280cfSShuo Chen /// Runs after finish pooling. 58354280cfSShuo Chen /// Safe to call from other threads. 59354280cfSShuo Chen void queueInLoop(const Functor& cb); 60354280cfSShuo Chen 61354280cfSShuo Chen // timers 62354280cfSShuo Chen 63354280cfSShuo Chen /// 64354280cfSShuo Chen /// Runs callback at 'time'. 65354280cfSShuo Chen /// Safe to call from other threads. 66354280cfSShuo Chen /// 67354280cfSShuo Chen TimerId runAt(const Timestamp& time, const TimerCallback& cb); 68354280cfSShuo Chen /// 69354280cfSShuo Chen /// Runs callback after @c delay seconds. 70354280cfSShuo Chen /// Safe to call from other threads. 71354280cfSShuo Chen /// 72354280cfSShuo Chen TimerId runAfter(double delay, const TimerCallback& cb); 73354280cfSShuo Chen /// 74354280cfSShuo Chen /// Runs callback every @c interval seconds. 75354280cfSShuo Chen /// Safe to call from other threads. 76354280cfSShuo Chen /// 77354280cfSShuo Chen TimerId runEvery(double interval, const TimerCallback& cb); 78354280cfSShuo Chen 79354280cfSShuo Chen void cancel(TimerId timerId); 80354280cfSShuo Chen 81354280cfSShuo Chen // internal use only 82354280cfSShuo Chen void wakeup(); 83354280cfSShuo Chen void updateChannel(Channel* channel); 84354280cfSShuo Chen void removeChannel(Channel* channel); 85354280cfSShuo Chen 86354280cfSShuo Chen void assertInLoopThread() 87354280cfSShuo Chen { 88354280cfSShuo Chen if (!isInLoopThread()) 89354280cfSShuo Chen { 90354280cfSShuo Chen abortNotInLoopThread(); 91354280cfSShuo Chen } 92354280cfSShuo Chen } 93354280cfSShuo Chen 94354280cfSShuo Chen bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); } 95354280cfSShuo Chen 96354280cfSShuo Chen private: 97354280cfSShuo Chen 98354280cfSShuo Chen void abortNotInLoopThread(); 99354280cfSShuo Chen void handleRead(); // waked up 100354280cfSShuo Chen void doPendingFunctors(); 101354280cfSShuo Chen 102354280cfSShuo Chen typedef std::vector<Channel*> ChannelList; 103354280cfSShuo Chen 104354280cfSShuo Chen bool looping_; /* atomic */ 105354280cfSShuo Chen bool quit_; /* atomic */ 106354280cfSShuo Chen bool callingPendingFunctors_; /* atomic */ 107354280cfSShuo Chen const pid_t threadId_; 108354280cfSShuo Chen Timestamp pollReturnTime_; 10970523619SShuo Chen boost::scoped_ptr<EPoller> poller_; 110354280cfSShuo Chen boost::scoped_ptr<TimerQueue> timerQueue_; 111354280cfSShuo Chen int wakeupFd_; 112354280cfSShuo Chen // unlike in TimerQueue, which is an internal class, 113354280cfSShuo Chen // we don't expose Channel to client. 114354280cfSShuo Chen boost::scoped_ptr<Channel> wakeupChannel_; 115354280cfSShuo Chen ChannelList activeChannels_; 116354280cfSShuo Chen MutexLock mutex_; 117354280cfSShuo Chen std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_ 118354280cfSShuo Chen}; 119354280cfSShuo Chen 120354280cfSShuo Chen} 121354280cfSShuo Chen 122354280cfSShuo Chen#endif // MUDUO_NET_EVENTLOOP_H 123