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