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