Poller.cc revision 17c057c3
1cc7f415cSShuo Chen// excerpts from http://code.google.com/p/muduo/
2cc7f415cSShuo Chen//
3cc7f415cSShuo Chen// Use of this source code is governed by a BSD-style license
4cc7f415cSShuo Chen// that can be found in the License file.
5cc7f415cSShuo Chen//
6cc7f415cSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
7cc7f415cSShuo Chen
8cc7f415cSShuo Chen#include "Poller.h"
9cc7f415cSShuo Chen
10cc7f415cSShuo Chen#include "Channel.h"
11cc7f415cSShuo Chen#include "logging/Logging.h"
12cc7f415cSShuo Chen
13cc7f415cSShuo Chen#include <assert.h>
14cc7f415cSShuo Chen#include <poll.h>
15cc7f415cSShuo Chen
16cc7f415cSShuo Chenusing namespace muduo;
17cc7f415cSShuo Chen
18cc7f415cSShuo ChenPoller::Poller(EventLoop* loop)
19cc7f415cSShuo Chen  : ownerLoop_(loop)
20cc7f415cSShuo Chen{
21cc7f415cSShuo Chen}
22cc7f415cSShuo Chen
23cc7f415cSShuo ChenPoller::~Poller()
24cc7f415cSShuo Chen{
25cc7f415cSShuo Chen}
26cc7f415cSShuo Chen
27cc7f415cSShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels)
28cc7f415cSShuo Chen{
29cc7f415cSShuo Chen  // XXX pollfds_ shouldn't change
30cc7f415cSShuo Chen  int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs);
31cc7f415cSShuo Chen  Timestamp now(Timestamp::now());
32cc7f415cSShuo Chen  if (numEvents > 0)
33cc7f415cSShuo Chen  {
34cc7f415cSShuo Chen    LOG_TRACE << numEvents << " events happended";
35cc7f415cSShuo Chen    fillActiveChannels(numEvents, activeChannels);
36cc7f415cSShuo Chen  }
37cc7f415cSShuo Chen  else if (numEvents == 0)
38cc7f415cSShuo Chen  {
39cc7f415cSShuo Chen    LOG_TRACE << " nothing happended";
40cc7f415cSShuo Chen  }
41cc7f415cSShuo Chen  else
42cc7f415cSShuo Chen  {
43cc7f415cSShuo Chen    LOG_SYSERR << "Poller::poll()";
44cc7f415cSShuo Chen  }
45cc7f415cSShuo Chen  return now;
46cc7f415cSShuo Chen}
47cc7f415cSShuo Chen
48cc7f415cSShuo Chenvoid Poller::fillActiveChannels(int numEvents,
49cc7f415cSShuo Chen                                ChannelList* activeChannels) const
50cc7f415cSShuo Chen{
51cc7f415cSShuo Chen  for (PollFdList::const_iterator pfd = pollfds_.begin();
52cc7f415cSShuo Chen      pfd != pollfds_.end() && numEvents > 0; ++pfd)
53cc7f415cSShuo Chen  {
54cc7f415cSShuo Chen    if (pfd->revents > 0)
55cc7f415cSShuo Chen    {
56cc7f415cSShuo Chen      --numEvents;
57cc7f415cSShuo Chen      ChannelMap::const_iterator ch = channels_.find(pfd->fd);
58cc7f415cSShuo Chen      assert(ch != channels_.end());
59cc7f415cSShuo Chen      Channel* channel = ch->second;
60cc7f415cSShuo Chen      assert(channel->fd() == pfd->fd);
61cc7f415cSShuo Chen      channel->set_revents(pfd->revents);
62cc7f415cSShuo Chen      // pfd->revents = 0;
63cc7f415cSShuo Chen      activeChannels->push_back(channel);
64cc7f415cSShuo Chen    }
65cc7f415cSShuo Chen  }
66cc7f415cSShuo Chen}
67cc7f415cSShuo Chen
68cc7f415cSShuo Chenvoid Poller::updateChannel(Channel* channel)
69cc7f415cSShuo Chen{
70cc7f415cSShuo Chen  Poller::assertInLoopThread();
71cc7f415cSShuo Chen  LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events();
72cc7f415cSShuo Chen  if (channel->index() < 0)
73cc7f415cSShuo Chen  {
74cc7f415cSShuo Chen    // a new one, add to pollfds_
75cc7f415cSShuo Chen    assert(channels_.find(channel->fd()) == channels_.end());
76cc7f415cSShuo Chen    struct pollfd pfd;
77cc7f415cSShuo Chen    pfd.fd = channel->fd();
78cc7f415cSShuo Chen    pfd.events = static_cast<short>(channel->events());
79cc7f415cSShuo Chen    pfd.revents = 0;
80cc7f415cSShuo Chen    pollfds_.push_back(pfd);
81cc7f415cSShuo Chen    int idx = static_cast<int>(pollfds_.size())-1;
82cc7f415cSShuo Chen    channel->set_index(idx);
83cc7f415cSShuo Chen    channels_[pfd.fd] = channel;
84cc7f415cSShuo Chen  }
85cc7f415cSShuo Chen  else
86cc7f415cSShuo Chen  {
87cc7f415cSShuo Chen    // update existing one
88cc7f415cSShuo Chen    assert(channels_.find(channel->fd()) != channels_.end());
89cc7f415cSShuo Chen    assert(channels_[channel->fd()] == channel);
90cc7f415cSShuo Chen    int idx = channel->index();
91cc7f415cSShuo Chen    assert(0 <= idx && idx < static_cast<int>(pollfds_.size()));
92cc7f415cSShuo Chen    struct pollfd& pfd = pollfds_[idx];
93cc7f415cSShuo Chen    assert(pfd.fd == channel->fd() || pfd.fd == -1);
9417c057c3SShuo Chen    pfd.events = static_cast<short>(channel->events());
9517c057c3SShuo Chen    pfd.revents = 0;
960615e80eSShuo Chen    if (channel->isNoneEvent())
97cc7f415cSShuo Chen    {
98cc7f415cSShuo Chen      // ignore this pollfd
99cc7f415cSShuo Chen      pfd.fd = -1;
100cc7f415cSShuo Chen    }
101cc7f415cSShuo Chen  }
102cc7f415cSShuo Chen}
103cc7f415cSShuo Chen
104