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