1566406ccSShuo Chen // excerpts from http://code.google.com/p/muduo/
2566406ccSShuo Chen //
3566406ccSShuo Chen // Use of this source code is governed by a BSD-style license
4566406ccSShuo Chen // that can be found in the License file.
5566406ccSShuo Chen //
6566406ccSShuo Chen // Author: Shuo Chen (chenshuo at chenshuo dot com)
7566406ccSShuo Chen 
8566406ccSShuo Chen #include "EventLoop.h"
9566406ccSShuo Chen 
10566406ccSShuo Chen #include "Channel.h"
11566406ccSShuo Chen #include "Poller.h"
12566406ccSShuo Chen+#include "TimerQueue.h"
13566406ccSShuo Chen 
14566406ccSShuo Chen #include "logging/Logging.h"
15566406ccSShuo Chen 
16566406ccSShuo Chen #include <assert.h>
17566406ccSShuo Chen 
18566406ccSShuo Chen using namespace muduo;
19566406ccSShuo Chen 
20566406ccSShuo Chen __thread EventLoop* t_loopInThisThread = 0;
21566406ccSShuo Chen const int kPollTimeMs = 10000;
22566406ccSShuo Chen 
23566406ccSShuo Chen EventLoop::EventLoop()
24566406ccSShuo Chen   : looping_(false),
25566406ccSShuo Chen     quit_(false),
26566406ccSShuo Chen     threadId_(CurrentThread::tid()),
27566406ccSShuo Chen     poller_(new Poller(this)),
28566406ccSShuo Chen+    timerQueue_(new TimerQueue(this))
29566406ccSShuo Chen {
30566406ccSShuo Chen   LOG_TRACE << "EventLoop created " << this << " in thread " << threadId_;
31566406ccSShuo Chen   if (t_loopInThisThread)
32566406ccSShuo Chen   {
33566406ccSShuo Chen     LOG_FATAL << "Another EventLoop " << t_loopInThisThread
34566406ccSShuo Chen               << " exists in this thread " << threadId_;
35566406ccSShuo Chen   }
36566406ccSShuo Chen   else
37566406ccSShuo Chen   {
38566406ccSShuo Chen     t_loopInThisThread = this;
39566406ccSShuo Chen   }
40566406ccSShuo Chen }
41566406ccSShuo Chen 
42566406ccSShuo Chen EventLoop::~EventLoop()
43566406ccSShuo Chen {
44566406ccSShuo Chen   assert(!looping_);
45566406ccSShuo Chen   t_loopInThisThread = NULL;
46566406ccSShuo Chen }
47566406ccSShuo Chen 
48566406ccSShuo Chen void EventLoop::loop()
49566406ccSShuo Chen {
50566406ccSShuo Chen   assert(!looping_);
51566406ccSShuo Chen   assertInLoopThread();
52566406ccSShuo Chen   looping_ = true;
53566406ccSShuo Chen   quit_ = false;
54566406ccSShuo Chen 
55566406ccSShuo Chen   while (!quit_)
56566406ccSShuo Chen   {
57566406ccSShuo Chen     activeChannels_.clear();
58566406ccSShuo Chen!    pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_);
59566406ccSShuo Chen     for (ChannelList::iterator it = activeChannels_.begin();
60566406ccSShuo Chen         it != activeChannels_.end(); ++it)
61566406ccSShuo Chen     {
62566406ccSShuo Chen       (*it)->handleEvent();
63566406ccSShuo Chen     }
64566406ccSShuo Chen   }
65566406ccSShuo Chen 
66566406ccSShuo Chen   LOG_TRACE << "EventLoop " << this << " stop looping";
67566406ccSShuo Chen   looping_ = false;
68566406ccSShuo Chen }
69566406ccSShuo Chen 
70566406ccSShuo Chen void EventLoop::quit()
71566406ccSShuo Chen {
72566406ccSShuo Chen   quit_ = true;
73566406ccSShuo Chen   // wakeup();
74566406ccSShuo Chen }
75566406ccSShuo Chen 
76566406ccSShuo Chen+TimerId EventLoop::runAt(const Timestamp& time, const TimerCallback& cb)
77566406ccSShuo Chen+{
78566406ccSShuo Chen+  return timerQueue_->addTimer(cb, time, 0.0);
79566406ccSShuo Chen+}
80566406ccSShuo Chen+
81566406ccSShuo Chen+TimerId EventLoop::runAfter(double delay, const TimerCallback& cb)
82566406ccSShuo Chen+{
83566406ccSShuo Chen+  Timestamp time(addTime(Timestamp::now(), delay));
84566406ccSShuo Chen+  return runAt(time, cb);
85566406ccSShuo Chen+}
86566406ccSShuo Chen+
87566406ccSShuo Chen+TimerId EventLoop::runEvery(double interval, const TimerCallback& cb)
88566406ccSShuo Chen+{
89566406ccSShuo Chen+  Timestamp time(addTime(Timestamp::now(), interval));
90566406ccSShuo Chen+  return timerQueue_->addTimer(cb, time, interval);
91566406ccSShuo Chen+}
92566406ccSShuo Chen+
93566406ccSShuo Chen void EventLoop::updateChannel(Channel* channel)
94566406ccSShuo Chen {
95566406ccSShuo Chen   assert(channel->ownerLoop() == this);
96566406ccSShuo Chen   assertInLoopThread();
97566406ccSShuo Chen   poller_->updateChannel(channel);
98566406ccSShuo Chen }
99566406ccSShuo Chen 
100566406ccSShuo Chen void EventLoop::abortNotInLoopThread()
101566406ccSShuo Chen {
102566406ccSShuo Chen   LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this
103566406ccSShuo Chen             << " was created in threadId_ = " << threadId_
104566406ccSShuo Chen             << ", current thread id = " <<  CurrentThread::tid();
105566406ccSShuo Chen }
106566406ccSShuo Chen 
107