EventLoop.cc revision e44bbe65
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