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 
18 using namespace muduo;
19 
20 __thread EventLoop* t_loopInThisThread = 0;
21 const int kPollTimeMs = 10000;
22 
23 EventLoop::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 
42 EventLoop::~EventLoop()
43 {
44   assert(!looping_);
45   t_loopInThisThread = NULL;
46 }
47 
48 void 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 
70 void EventLoop::quit()
71 {
72   quit_ = true;
73   // wakeup();
74 }
75 
76+TimerId EventLoop::runAt(const Timestamp& time, const TimerCallback& cb)
77+{
78+  return timerQueue_->addTimer(cb, time, 0.0);
79+}
80+
81+TimerId EventLoop::runAfter(double delay, const TimerCallback& cb)
82+{
83+  Timestamp time(addTime(Timestamp::now(), delay));
84+  return runAt(time, cb);
85+}
86+
87+TimerId EventLoop::runEvery(double interval, const TimerCallback& cb)
88+{
89+  Timestamp time(addTime(Timestamp::now(), interval));
90+  return timerQueue_->addTimer(cb, time, interval);
91+}
92+
93 void EventLoop::updateChannel(Channel* channel)
94 {
95   assert(channel->ownerLoop() == this);
96   assertInLoopThread();
97   poller_->updateChannel(channel);
98 }
99 
100 void 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