1cbe8e7d0SShuo Chen// excerpts from http://code.google.com/p/muduo/ 2cbe8e7d0SShuo Chen// 3cbe8e7d0SShuo Chen// Use of this source code is governed by a BSD-style license 4cbe8e7d0SShuo Chen// that can be found in the License file. 5cbe8e7d0SShuo Chen// 6cbe8e7d0SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 7cbe8e7d0SShuo Chen 8cbe8e7d0SShuo Chen#include "EventLoop.h" 9cbe8e7d0SShuo Chen 10cbe8e7d0SShuo Chen#include "Channel.h" 11cbe8e7d0SShuo Chen#include "Poller.h" 1242bf2220SShuo Chen#include "TimerQueue.h" 13cbe8e7d0SShuo Chen 14cbe8e7d0SShuo Chen#include "logging/Logging.h" 15cbe8e7d0SShuo Chen 16cbe8e7d0SShuo Chen#include <assert.h> 17cbe8e7d0SShuo Chen 18cbe8e7d0SShuo Chenusing namespace muduo; 19cbe8e7d0SShuo Chen 20cbe8e7d0SShuo Chen__thread EventLoop* t_loopInThisThread = 0; 21cbe8e7d0SShuo Chenconst int kPollTimeMs = 10000; 22cbe8e7d0SShuo Chen 23cbe8e7d0SShuo ChenEventLoop::EventLoop() 24cbe8e7d0SShuo Chen : looping_(false), 25cbe8e7d0SShuo Chen quit_(false), 26cbe8e7d0SShuo Chen threadId_(CurrentThread::tid()), 2742bf2220SShuo Chen poller_(new Poller(this)), 2842bf2220SShuo Chen timerQueue_(new TimerQueue(this)) 29cbe8e7d0SShuo Chen{ 30cbe8e7d0SShuo Chen LOG_TRACE << "EventLoop created " << this << " in thread " << threadId_; 31cbe8e7d0SShuo Chen if (t_loopInThisThread) 32cbe8e7d0SShuo Chen { 33cbe8e7d0SShuo Chen LOG_FATAL << "Another EventLoop " << t_loopInThisThread 34cbe8e7d0SShuo Chen << " exists in this thread " << threadId_; 35cbe8e7d0SShuo Chen } 36cbe8e7d0SShuo Chen else 37cbe8e7d0SShuo Chen { 38cbe8e7d0SShuo Chen t_loopInThisThread = this; 39cbe8e7d0SShuo Chen } 40cbe8e7d0SShuo Chen} 41cbe8e7d0SShuo Chen 42cbe8e7d0SShuo ChenEventLoop::~EventLoop() 43cbe8e7d0SShuo Chen{ 44cbe8e7d0SShuo Chen assert(!looping_); 45cbe8e7d0SShuo Chen t_loopInThisThread = NULL; 46cbe8e7d0SShuo Chen} 47cbe8e7d0SShuo Chen 48cbe8e7d0SShuo Chenvoid EventLoop::loop() 49cbe8e7d0SShuo Chen{ 50cbe8e7d0SShuo Chen assert(!looping_); 51cbe8e7d0SShuo Chen assertInLoopThread(); 52cbe8e7d0SShuo Chen looping_ = true; 53e44bbe65SShuo Chen quit_ = false; 54e44bbe65SShuo Chen 55cbe8e7d0SShuo Chen while (!quit_) 56cbe8e7d0SShuo Chen { 57cbe8e7d0SShuo Chen activeChannels_.clear(); 5842bf2220SShuo Chen pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_); 59cbe8e7d0SShuo Chen for (ChannelList::iterator it = activeChannels_.begin(); 60cbe8e7d0SShuo Chen it != activeChannels_.end(); ++it) 61cbe8e7d0SShuo Chen { 62cbe8e7d0SShuo Chen (*it)->handleEvent(); 63cbe8e7d0SShuo Chen } 64cbe8e7d0SShuo Chen } 65cbe8e7d0SShuo Chen 66cbe8e7d0SShuo Chen LOG_TRACE << "EventLoop " << this << " stop looping"; 67cbe8e7d0SShuo Chen looping_ = false; 68cbe8e7d0SShuo Chen} 69cbe8e7d0SShuo Chen 70cbe8e7d0SShuo Chenvoid EventLoop::quit() 71cbe8e7d0SShuo Chen{ 72cbe8e7d0SShuo Chen quit_ = true; 73cbe8e7d0SShuo Chen // wakeup(); 74cbe8e7d0SShuo Chen} 75cbe8e7d0SShuo Chen 7642bf2220SShuo ChenTimerId EventLoop::runAt(const Timestamp& time, const TimerCallback& cb) 7742bf2220SShuo Chen{ 7842bf2220SShuo Chen return timerQueue_->addTimer(cb, time, 0.0); 7942bf2220SShuo Chen} 8042bf2220SShuo Chen 8142bf2220SShuo ChenTimerId EventLoop::runAfter(double delay, const TimerCallback& cb) 8242bf2220SShuo Chen{ 8342bf2220SShuo Chen Timestamp time(addTime(Timestamp::now(), delay)); 8442bf2220SShuo Chen return runAt(time, cb); 8542bf2220SShuo Chen} 8642bf2220SShuo Chen 8742bf2220SShuo ChenTimerId EventLoop::runEvery(double interval, const TimerCallback& cb) 8842bf2220SShuo Chen{ 8942bf2220SShuo Chen Timestamp time(addTime(Timestamp::now(), interval)); 9042bf2220SShuo Chen return timerQueue_->addTimer(cb, time, interval); 9142bf2220SShuo Chen} 9242bf2220SShuo Chen 93cbe8e7d0SShuo Chenvoid EventLoop::updateChannel(Channel* channel) 94cbe8e7d0SShuo Chen{ 95cbe8e7d0SShuo Chen assert(channel->ownerLoop() == this); 96cbe8e7d0SShuo Chen assertInLoopThread(); 97cbe8e7d0SShuo Chen poller_->updateChannel(channel); 98cbe8e7d0SShuo Chen} 99cbe8e7d0SShuo Chen 100cbe8e7d0SShuo Chenvoid EventLoop::abortNotInLoopThread() 101cbe8e7d0SShuo Chen{ 102cbe8e7d0SShuo Chen LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this 103cbe8e7d0SShuo Chen << " was created in threadId_ = " << threadId_ 104cbe8e7d0SShuo Chen << ", current thread id = " << CurrentThread::tid(); 105cbe8e7d0SShuo Chen} 106cbe8e7d0SShuo Chen 107