12a18e699SShuo Chen// excerpts from http://code.google.com/p/muduo/ 22a18e699SShuo Chen// 32a18e699SShuo Chen// Use of this source code is governed by a BSD-style license 42a18e699SShuo Chen// that can be found in the License file. 52a18e699SShuo Chen// 62a18e699SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 72a18e699SShuo Chen 82a18e699SShuo Chen#ifndef MUDUO_NET_EVENTLOOP_H 92a18e699SShuo Chen#define MUDUO_NET_EVENTLOOP_H 102a18e699SShuo Chen 112a18e699SShuo Chen#include "datetime/Timestamp.h" 122a18e699SShuo Chen#include "thread/Mutex.h" 132a18e699SShuo Chen#include "thread/Thread.h" 142a18e699SShuo Chen#include "Callbacks.h" 152a18e699SShuo Chen#include "TimerId.h" 162a18e699SShuo Chen 172a18e699SShuo Chen#include <boost/scoped_ptr.hpp> 182a18e699SShuo Chen#include <vector> 192a18e699SShuo Chen 202a18e699SShuo Chennamespace muduo 212a18e699SShuo Chen{ 222a18e699SShuo Chen 232a18e699SShuo Chenclass Channel; 242a18e699SShuo Chenclass Poller; 252a18e699SShuo Chenclass TimerQueue; 262a18e699SShuo Chen 272a18e699SShuo Chenclass EventLoop : boost::noncopyable 282a18e699SShuo Chen{ 292a18e699SShuo Chen public: 302a18e699SShuo Chen typedef boost::function<void()> Functor; 312a18e699SShuo Chen 322a18e699SShuo Chen EventLoop(); 332a18e699SShuo Chen 342a18e699SShuo Chen // force out-line dtor, for scoped_ptr members. 352a18e699SShuo Chen ~EventLoop(); 362a18e699SShuo Chen 372a18e699SShuo Chen /// 382a18e699SShuo Chen /// Loops forever. 392a18e699SShuo Chen /// 402a18e699SShuo Chen /// Must be called in the same thread as creation of the object. 412a18e699SShuo Chen /// 422a18e699SShuo Chen void loop(); 432a18e699SShuo Chen 442a18e699SShuo Chen void quit(); 452a18e699SShuo Chen 462a18e699SShuo Chen /// 472a18e699SShuo Chen /// Time when poll returns, usually means data arrivial. 482a18e699SShuo Chen /// 492a18e699SShuo Chen Timestamp pollReturnTime() const { return pollReturnTime_; } 502a18e699SShuo Chen 512a18e699SShuo Chen /// Runs callback immediately in the loop thread. 522a18e699SShuo Chen /// It wakes up the loop, and run the cb. 532a18e699SShuo Chen /// If in the same loop thread, cb is run within the function. 542a18e699SShuo Chen /// Safe to call from other threads. 552a18e699SShuo Chen void runInLoop(const Functor& cb); 562a18e699SShuo Chen /// Queues callback in the loop thread. 572a18e699SShuo Chen /// Runs after finish pooling. 582a18e699SShuo Chen /// Safe to call from other threads. 592a18e699SShuo Chen void queueInLoop(const Functor& cb); 602a18e699SShuo Chen 612a18e699SShuo Chen // timers 622a18e699SShuo Chen 632a18e699SShuo Chen /// 642a18e699SShuo Chen /// Runs callback at 'time'. 652a18e699SShuo Chen /// Safe to call from other threads. 662a18e699SShuo Chen /// 672a18e699SShuo Chen TimerId runAt(const Timestamp& time, const TimerCallback& cb); 682a18e699SShuo Chen /// 692a18e699SShuo Chen /// Runs callback after @c delay seconds. 702a18e699SShuo Chen /// Safe to call from other threads. 712a18e699SShuo Chen /// 722a18e699SShuo Chen TimerId runAfter(double delay, const TimerCallback& cb); 732a18e699SShuo Chen /// 742a18e699SShuo Chen /// Runs callback every @c interval seconds. 752a18e699SShuo Chen /// Safe to call from other threads. 762a18e699SShuo Chen /// 772a18e699SShuo Chen TimerId runEvery(double interval, const TimerCallback& cb); 782a18e699SShuo Chen 792a18e699SShuo Chen // void cancel(TimerId timerId); 802a18e699SShuo Chen 812a18e699SShuo Chen // internal use only 822a18e699SShuo Chen void wakeup(); 832a18e699SShuo Chen void updateChannel(Channel* channel); 842a18e699SShuo Chen void removeChannel(Channel* channel); 852a18e699SShuo Chen 862a18e699SShuo Chen void assertInLoopThread() 872a18e699SShuo Chen { 882a18e699SShuo Chen if (!isInLoopThread()) 892a18e699SShuo Chen { 902a18e699SShuo Chen abortNotInLoopThread(); 912a18e699SShuo Chen } 922a18e699SShuo Chen } 932a18e699SShuo Chen 942a18e699SShuo Chen bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); } 952a18e699SShuo Chen 962a18e699SShuo Chen private: 972a18e699SShuo Chen 982a18e699SShuo Chen void abortNotInLoopThread(); 992a18e699SShuo Chen void handleRead(); // waked up 1002a18e699SShuo Chen void doPendingFunctors(); 1012a18e699SShuo Chen 1022a18e699SShuo Chen typedef std::vector<Channel*> ChannelList; 1032a18e699SShuo Chen 1042a18e699SShuo Chen bool looping_; /* atomic */ 1052a18e699SShuo Chen bool quit_; /* atomic */ 1062a18e699SShuo Chen bool callingPendingFunctors_; /* atomic */ 1072a18e699SShuo Chen const pid_t threadId_; 1082a18e699SShuo Chen Timestamp pollReturnTime_; 1092a18e699SShuo Chen boost::scoped_ptr<Poller> poller_; 1102a18e699SShuo Chen boost::scoped_ptr<TimerQueue> timerQueue_; 1112a18e699SShuo Chen int wakeupFd_; 1122a18e699SShuo Chen // unlike in TimerQueue, which is an internal class, 1132a18e699SShuo Chen // we don't expose Channel to client. 1142a18e699SShuo Chen boost::scoped_ptr<Channel> wakeupChannel_; 1152a18e699SShuo Chen ChannelList activeChannels_; 1162a18e699SShuo Chen MutexLock mutex_; 117fd65b0afSShuo Chen std::vector<Functor> pendingFunctors_; // @GuardedBy mutex_ 1182a18e699SShuo Chen}; 1192a18e699SShuo Chen 1202a18e699SShuo Chen} 1212a18e699SShuo Chen 1222a18e699SShuo Chen#endif // MUDUO_NET_EVENTLOOP_H 123