EventLoop.h revision 40161064
140161064SShuo Chen// excerpts from http://code.google.com/p/muduo/ 240161064SShuo Chen// 340161064SShuo Chen// Use of this source code is governed by a BSD-style license 440161064SShuo Chen// that can be found in the License file. 540161064SShuo Chen// 640161064SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 740161064SShuo Chen 840161064SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H 940161064SShuo Chen#define MUDUO_NET_EVENTLOOP_H 1040161064SShuo Chen 1140161064SShuo Chen#include "datetime/Timestamp.h" 1240161064SShuo Chen#include "thread/Mutex.h" 1340161064SShuo Chen#include "thread/Thread.h" 1440161064SShuo Chen#include "Callbacks.h" 1540161064SShuo Chen#include "TimerId.h" 1640161064SShuo Chen 1740161064SShuo Chen#include <boost/scoped_ptr.hpp> 1840161064SShuo Chen#include <vector> 1940161064SShuo Chen 2040161064SShuo Chennamespace muduo 2140161064SShuo Chen{ 2240161064SShuo Chen 2340161064SShuo Chenclass Channel; 2440161064SShuo Chenclass Poller; 2540161064SShuo Chenclass TimerQueue; 2640161064SShuo Chen 2740161064SShuo Chenclass EventLoop : boost::noncopyable 2840161064SShuo Chen{ 2940161064SShuo Chen public: 3040161064SShuo Chen typedef boost::function<void()> Functor; 3140161064SShuo Chen 3240161064SShuo Chen EventLoop(); 3340161064SShuo Chen 3440161064SShuo Chen // force out-line dtor, for scoped_ptr members. 3540161064SShuo Chen ~EventLoop(); 3640161064SShuo Chen 3740161064SShuo Chen /// 3840161064SShuo Chen /// Loops forever. 3940161064SShuo Chen /// 4040161064SShuo Chen /// Must be called in the same thread as creation of the object. 4140161064SShuo Chen /// 4240161064SShuo Chen void loop(); 4340161064SShuo Chen 4440161064SShuo Chen void quit(); 4540161064SShuo Chen 4640161064SShuo Chen /// 4740161064SShuo Chen /// Time when poll returns, usually means data arrivial. 4840161064SShuo Chen /// 4940161064SShuo Chen Timestamp pollReturnTime() const { return pollReturnTime_; } 5040161064SShuo Chen 5140161064SShuo Chen /// Runs callback immediately in the loop thread. 5240161064SShuo Chen /// It wakes up the loop, and run the cb. 5340161064SShuo Chen /// If in the same loop thread, cb is run within the function. 5440161064SShuo Chen /// Safe to call from other threads. 5540161064SShuo Chen void runInLoop(const Functor& cb); 5640161064SShuo Chen /// Queues callback in the loop thread. 5740161064SShuo Chen /// Runs after finish pooling. 5840161064SShuo Chen /// Safe to call from other threads. 5940161064SShuo Chen void queueInLoop(const Functor& cb); 6040161064SShuo Chen 6140161064SShuo Chen // timers 6240161064SShuo Chen 6340161064SShuo Chen /// 6440161064SShuo Chen /// Runs callback at 'time'. 6540161064SShuo Chen /// Safe to call from other threads. 6640161064SShuo Chen /// 6740161064SShuo Chen TimerId runAt(const Timestamp& time, const TimerCallback& cb); 6840161064SShuo Chen /// 6940161064SShuo Chen /// Runs callback after @c delay seconds. 7040161064SShuo Chen /// Safe to call from other threads. 7140161064SShuo Chen /// 7240161064SShuo Chen TimerId runAfter(double delay, const TimerCallback& cb); 7340161064SShuo Chen /// 7440161064SShuo Chen /// Runs callback every @c interval seconds. 7540161064SShuo Chen /// Safe to call from other threads. 7640161064SShuo Chen /// 7740161064SShuo Chen TimerId runEvery(double interval, const TimerCallback& cb); 7840161064SShuo Chen 7940161064SShuo Chen // void cancel(TimerId timerId); 8040161064SShuo Chen 8140161064SShuo Chen // internal use only 8240161064SShuo Chen void wakeup(); 8340161064SShuo Chen void updateChannel(Channel* channel); 8440161064SShuo Chen void removeChannel(Channel* channel); 8540161064SShuo Chen 8640161064SShuo Chen void assertInLoopThread() 8740161064SShuo Chen { 8840161064SShuo Chen if (!isInLoopThread()) 8940161064SShuo Chen { 9040161064SShuo Chen abortNotInLoopThread(); 9140161064SShuo Chen } 9240161064SShuo Chen } 9340161064SShuo Chen 9440161064SShuo Chen bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); } 9540161064SShuo Chen 9640161064SShuo Chen private: 9740161064SShuo Chen 9840161064SShuo Chen void abortNotInLoopThread(); 9940161064SShuo Chen void handleRead(); // waked up 10040161064SShuo Chen void doPendingFunctors(); 10140161064SShuo Chen 10240161064SShuo Chen typedef std::vector<Channel*> ChannelList; 10340161064SShuo Chen 10440161064SShuo Chen bool looping_; /* atomic */ 10540161064SShuo Chen bool quit_; /* atomic */ 10640161064SShuo Chen bool callingPendingFunctors_; /* atomic */ 10740161064SShuo Chen const pid_t threadId_; 10840161064SShuo Chen Timestamp pollReturnTime_; 10940161064SShuo Chen boost::scoped_ptr<Poller> poller_; 11040161064SShuo Chen boost::scoped_ptr<TimerQueue> timerQueue_; 11140161064SShuo Chen int wakeupFd_; 11240161064SShuo Chen // unlike in TimerQueue, which is an internal class, 11340161064SShuo Chen // we don't expose Channel to client. 11440161064SShuo Chen boost::scoped_ptr<Channel> wakeupChannel_; 11540161064SShuo Chen ChannelList activeChannels_; 11640161064SShuo Chen MutexLock mutex_; 11740161064SShuo Chen std::vector<Functor> pendingFunctors_; // @BuardedBy mutex_ 11840161064SShuo Chen}; 11940161064SShuo Chen 12040161064SShuo Chen} 12140161064SShuo Chen 12240161064SShuo Chen#endif // MUDUO_NET_EVENTLOOP_H 123