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