Poller.cc revision ee021d99
12745a763SShuo Chen// excerpts from http://code.google.com/p/muduo/
22745a763SShuo Chen//
32745a763SShuo Chen// Use of this source code is governed by a BSD-style license
42745a763SShuo Chen// that can be found in the License file.
52745a763SShuo Chen//
62745a763SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
72745a763SShuo Chen
82745a763SShuo Chen#include "Poller.h"
92745a763SShuo Chen
102745a763SShuo Chen#include "Channel.h"
112745a763SShuo Chen#include "logging/Logging.h"
122745a763SShuo Chen
132745a763SShuo Chen#include <assert.h>
142745a763SShuo Chen#include <poll.h>
152745a763SShuo Chen
162745a763SShuo Chenusing namespace muduo;
172745a763SShuo Chen
182745a763SShuo ChenPoller::Poller(EventLoop* loop)
192745a763SShuo Chen  : ownerLoop_(loop)
202745a763SShuo Chen{
212745a763SShuo Chen}
222745a763SShuo Chen
232745a763SShuo ChenPoller::~Poller()
242745a763SShuo Chen{
252745a763SShuo Chen}
262745a763SShuo Chen
272745a763SShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels)
282745a763SShuo Chen{
292745a763SShuo Chen  // XXX pollfds_ shouldn't change
302745a763SShuo Chen  int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs);
312745a763SShuo Chen  Timestamp now(Timestamp::now());
322745a763SShuo Chen  if (numEvents > 0)
332745a763SShuo Chen  {
342745a763SShuo Chen    LOG_TRACE << numEvents << " events happended";
352745a763SShuo Chen    fillActiveChannels(numEvents, activeChannels);
362745a763SShuo Chen  }
372745a763SShuo Chen  else if (numEvents == 0)
382745a763SShuo Chen  {
392745a763SShuo Chen    LOG_TRACE << " nothing happended";
402745a763SShuo Chen  }
412745a763SShuo Chen  else
422745a763SShuo Chen  {
432745a763SShuo Chen    LOG_SYSERR << "Poller::poll()";
442745a763SShuo Chen  }
452745a763SShuo Chen  return now;
462745a763SShuo Chen}
472745a763SShuo Chen
482745a763SShuo Chenvoid Poller::fillActiveChannels(int numEvents,
492745a763SShuo Chen                                ChannelList* activeChannels) const
502745a763SShuo Chen{
512745a763SShuo Chen  for (PollFdList::const_iterator pfd = pollfds_.begin();
522745a763SShuo Chen      pfd != pollfds_.end() && numEvents > 0; ++pfd)
532745a763SShuo Chen  {
542745a763SShuo Chen    if (pfd->revents > 0)
552745a763SShuo Chen    {
562745a763SShuo Chen      --numEvents;
572745a763SShuo Chen      ChannelMap::const_iterator ch = channels_.find(pfd->fd);
582745a763SShuo Chen      assert(ch != channels_.end());
592745a763SShuo Chen      Channel* channel = ch->second;
602745a763SShuo Chen      assert(channel->fd() == pfd->fd);
612745a763SShuo Chen      channel->set_revents(pfd->revents);
622745a763SShuo Chen      // pfd->revents = 0;
632745a763SShuo Chen      activeChannels->push_back(channel);
642745a763SShuo Chen    }
652745a763SShuo Chen  }
662745a763SShuo Chen}
672745a763SShuo Chen
682745a763SShuo Chenvoid Poller::updateChannel(Channel* channel)
692745a763SShuo Chen{
70ee021d99SShuo Chen  assertInLoopThread();
712745a763SShuo Chen  LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events();
722745a763SShuo Chen  if (channel->index() < 0)
732745a763SShuo Chen  {
742745a763SShuo Chen    // a new one, add to pollfds_
752745a763SShuo Chen    assert(channels_.find(channel->fd()) == channels_.end());
762745a763SShuo Chen    struct pollfd pfd;
772745a763SShuo Chen    pfd.fd = channel->fd();
782745a763SShuo Chen    pfd.events = static_cast<short>(channel->events());
792745a763SShuo Chen    pfd.revents = 0;
802745a763SShuo Chen    pollfds_.push_back(pfd);
812745a763SShuo Chen    int idx = static_cast<int>(pollfds_.size())-1;
822745a763SShuo Chen    channel->set_index(idx);
832745a763SShuo Chen    channels_[pfd.fd] = channel;
842745a763SShuo Chen  }
852745a763SShuo Chen  else
862745a763SShuo Chen  {
872745a763SShuo Chen    // update existing one
882745a763SShuo Chen    assert(channels_.find(channel->fd()) != channels_.end());
892745a763SShuo Chen    assert(channels_[channel->fd()] == channel);
902745a763SShuo Chen    int idx = channel->index();
912745a763SShuo Chen    assert(0 <= idx && idx < static_cast<int>(pollfds_.size()));
922745a763SShuo Chen    struct pollfd& pfd = pollfds_[idx];
932745a763SShuo 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())
972745a763SShuo Chen    {
982745a763SShuo Chen      // ignore this pollfd
992745a763SShuo Chen      pfd.fd = -1;
1002745a763SShuo Chen    }
1012745a763SShuo Chen  }
1022745a763SShuo Chen}
1032745a763SShuo Chen
104