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