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