EventLoop.h revision fd65b0af
12745a763SShuo Chen// excerpts from http://code.google.com/p/muduo/ 22745a763SShuo Chen// 32745a763SShuo Chen// Use of this source code is governed by a BSD-style license 42745a763SShuo Chen// that can be found in the License file. 52745a763SShuo Chen// 62745a763SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 72745a763SShuo Chen 82745a763SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H 92745a763SShuo Chen#define MUDUO_NET_EVENTLOOP_H 102745a763SShuo Chen 112745a763SShuo Chen#include "datetime/Timestamp.h" 122745a763SShuo Chen#include "thread/Mutex.h" 132745a763SShuo Chen#include "thread/Thread.h" 142745a763SShuo Chen#include "Callbacks.h" 152745a763SShuo Chen#include "TimerId.h" 162745a763SShuo Chen 172745a763SShuo Chen#include <boost/scoped_ptr.hpp> 182745a763SShuo Chen#include <vector> 192745a763SShuo Chen 202745a763SShuo Chennamespace muduo 212745a763SShuo Chen{ 222745a763SShuo Chen 232745a763SShuo Chenclass Channel; 242745a763SShuo Chenclass Poller; 252745a763SShuo Chenclass TimerQueue; 262745a763SShuo Chen 272745a763SShuo Chenclass EventLoop : boost::noncopyable 282745a763SShuo Chen{ 292745a763SShuo Chen public: 302745a763SShuo Chen typedef boost::function<void()> Functor; 312745a763SShuo Chen 322745a763SShuo Chen EventLoop(); 332745a763SShuo Chen 342745a763SShuo Chen // force out-line dtor, for scoped_ptr members. 352745a763SShuo Chen ~EventLoop(); 362745a763SShuo Chen 372745a763SShuo Chen /// 382745a763SShuo Chen /// Loops forever. 392745a763SShuo Chen /// 402745a763SShuo Chen /// Must be called in the same thread as creation of the object. 412745a763SShuo Chen /// 422745a763SShuo Chen void loop(); 432745a763SShuo Chen 442745a763SShuo Chen void quit(); 452745a763SShuo Chen 462745a763SShuo Chen /// 472745a763SShuo Chen /// Time when poll returns, usually means data arrivial. 482745a763SShuo Chen /// 492745a763SShuo Chen Timestamp pollReturnTime() const { return pollReturnTime_; } 502745a763SShuo Chen 512745a763SShuo Chen /// Runs callback immediately in the loop thread. 522745a763SShuo Chen /// It wakes up the loop, and run the cb. 532745a763SShuo Chen /// If in the same loop thread, cb is run within the function. 542745a763SShuo Chen /// Safe to call from other threads. 552745a763SShuo Chen void runInLoop(const Functor& cb); 562745a763SShuo Chen /// Queues callback in the loop thread. 572745a763SShuo Chen /// Runs after finish pooling. 582745a763SShuo Chen /// Safe to call from other threads. 592745a763SShuo Chen void queueInLoop(const Functor& cb); 602745a763SShuo Chen 612745a763SShuo Chen // timers 622745a763SShuo Chen 632745a763SShuo Chen /// 642745a763SShuo Chen /// Runs callback at 'time'. 652745a763SShuo Chen /// Safe to call from other threads. 662745a763SShuo Chen /// 672745a763SShuo Chen TimerId runAt(const Timestamp& time, const TimerCallback& cb); 682745a763SShuo Chen /// 692745a763SShuo Chen /// Runs callback after @c delay seconds. 702745a763SShuo Chen /// Safe to call from other threads. 712745a763SShuo Chen /// 722745a763SShuo Chen TimerId runAfter(double delay, const TimerCallback& cb); 732745a763SShuo Chen /// 742745a763SShuo Chen /// Runs callback every @c interval seconds. 752745a763SShuo Chen /// Safe to call from other threads. 762745a763SShuo Chen /// 772745a763SShuo Chen TimerId runEvery(double interval, const TimerCallback& cb); 782745a763SShuo Chen 792745a763SShuo Chen // void cancel(TimerId timerId); 802745a763SShuo Chen 812745a763SShuo Chen // internal use only 822745a763SShuo Chen void wakeup(); 832745a763SShuo Chen void updateChannel(Channel* channel); 842745a763SShuo Chen // void removeChannel(Channel* channel); 852745a763SShuo Chen 862745a763SShuo Chen void assertInLoopThread() 872745a763SShuo Chen { 882745a763SShuo Chen if (!isInLoopThread()) 892745a763SShuo Chen { 902745a763SShuo Chen abortNotInLoopThread(); 912745a763SShuo Chen } 922745a763SShuo Chen } 932745a763SShuo Chen 942745a763SShuo Chen bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); } 952745a763SShuo Chen 962745a763SShuo Chen private: 972745a763SShuo Chen 982745a763SShuo Chen void abortNotInLoopThread(); 992745a763SShuo Chen void handleRead(); // waked up 1002745a763SShuo Chen void doPendingFunctors(); 1012745a763SShuo Chen 1022745a763SShuo Chen typedef std::vector<Channel*> ChannelList; 1032745a763SShuo Chen 1042745a763SShuo Chen bool looping_; /* atomic */ 1052745a763SShuo Chen bool quit_; /* atomic */ 1062745a763SShuo Chen bool callingPendingFunctors_; /* atomic */ 1072745a763SShuo Chen const pid_t threadId_; 1082745a763SShuo Chen Timestamp pollReturnTime_; 1092745a763SShuo Chen boost::scoped_ptr<Poller> poller_; 1102745a763SShuo Chen boost::scoped_ptr<TimerQueue> timerQueue_; 1112745a763SShuo Chen int wakeupFd_; 1122745a763SShuo Chen // unlike in TimerQueue, which is an internal class, 1132745a763SShuo Chen // we don't expose Channel to client. 1142745a763SShuo Chen boost::scoped_ptr<Channel> wakeupChannel_; 1152745a763SShuo Chen ChannelList activeChannels_; 1162745a763SShuo Chen MutexLock mutex_; 117fd65b0afSShuo Chen std::vector<Functor> pendingFunctors_; // @GuardedBy mutex_ 1182745a763SShuo Chen}; 1192745a763SShuo Chen 1202745a763SShuo Chen} 1212745a763SShuo Chen 1222745a763SShuo Chen#endif // MUDUO_NET_EVENTLOOP_H 123