1// excerpts from http://code.google.com/p/muduo/ 2// 3// Use of this source code is governed by a BSD-style license 4// that can be found in the License file. 5// 6// Author: Shuo Chen (chenshuo at chenshuo dot com) 7 8#include "EventLoop.h" 9 10#include "Channel.h" 11#include "Poller.h" 12#include "TimerQueue.h" 13 14#include "logging/Logging.h" 15 16#include <assert.h> 17 18using namespace muduo; 19 20__thread EventLoop* t_loopInThisThread = 0; 21const int kPollTimeMs = 10000; 22 23EventLoop::EventLoop() 24 : looping_(false), 25 quit_(false), 26 threadId_(CurrentThread::tid()), 27 poller_(new Poller(this)), 28 timerQueue_(new TimerQueue(this)) 29{ 30 LOG_TRACE << "EventLoop created " << this << " in thread " << threadId_; 31 if (t_loopInThisThread) 32 { 33 LOG_FATAL << "Another EventLoop " << t_loopInThisThread 34 << " exists in this thread " << threadId_; 35 } 36 else 37 { 38 t_loopInThisThread = this; 39 } 40} 41 42EventLoop::~EventLoop() 43{ 44 assert(!looping_); 45 t_loopInThisThread = NULL; 46} 47 48void EventLoop::loop() 49{ 50 assert(!looping_); 51 assertInLoopThread(); 52 looping_ = true; 53 quit_ = false; 54 55 while (!quit_) 56 { 57 activeChannels_.clear(); 58 pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_); 59 for (ChannelList::iterator it = activeChannels_.begin(); 60 it != activeChannels_.end(); ++it) 61 { 62 (*it)->handleEvent(); 63 } 64 } 65 66 LOG_TRACE << "EventLoop " << this << " stop looping"; 67 looping_ = false; 68} 69 70void EventLoop::quit() 71{ 72 quit_ = true; 73 // wakeup(); 74} 75 76TimerId EventLoop::runAt(const Timestamp& time, const TimerCallback& cb) 77{ 78 return timerQueue_->addTimer(cb, time, 0.0); 79} 80 81TimerId EventLoop::runAfter(double delay, const TimerCallback& cb) 82{ 83 Timestamp time(addTime(Timestamp::now(), delay)); 84 return runAt(time, cb); 85} 86 87TimerId EventLoop::runEvery(double interval, const TimerCallback& cb) 88{ 89 Timestamp time(addTime(Timestamp::now(), interval)); 90 return timerQueue_->addTimer(cb, time, interval); 91} 92 93void EventLoop::updateChannel(Channel* channel) 94{ 95 assert(channel->ownerLoop() == this); 96 assertInLoopThread(); 97 poller_->updateChannel(channel); 98} 99 100void EventLoop::abortNotInLoopThread() 101{ 102 LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this 103 << " was created in threadId_ = " << threadId_ 104 << ", current thread id = " << CurrentThread::tid(); 105} 106 107