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