Poller.cc revision ee021d99
19a1e991dSShuo Chen// excerpts from http://code.google.com/p/muduo/
29a1e991dSShuo Chen//
39a1e991dSShuo Chen// Use of this source code is governed by a BSD-style license
49a1e991dSShuo Chen// that can be found in the License file.
59a1e991dSShuo Chen//
69a1e991dSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com)
79a1e991dSShuo Chen
89a1e991dSShuo Chen#include "Poller.h"
99a1e991dSShuo Chen
109a1e991dSShuo Chen#include "Channel.h"
119a1e991dSShuo Chen#include "logging/Logging.h"
129a1e991dSShuo Chen
139a1e991dSShuo Chen#include <assert.h>
149a1e991dSShuo Chen#include <poll.h>
159a1e991dSShuo Chen
169a1e991dSShuo Chenusing namespace muduo;
179a1e991dSShuo Chen
189a1e991dSShuo ChenPoller::Poller(EventLoop* loop)
199a1e991dSShuo Chen  : ownerLoop_(loop)
209a1e991dSShuo Chen{
219a1e991dSShuo Chen}
229a1e991dSShuo Chen
239a1e991dSShuo ChenPoller::~Poller()
249a1e991dSShuo Chen{
259a1e991dSShuo Chen}
269a1e991dSShuo Chen
279a1e991dSShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels)
289a1e991dSShuo Chen{
299a1e991dSShuo Chen  // XXX pollfds_ shouldn't change
309a1e991dSShuo Chen  int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs);
319a1e991dSShuo Chen  Timestamp now(Timestamp::now());
329a1e991dSShuo Chen  if (numEvents > 0)
339a1e991dSShuo Chen  {
349a1e991dSShuo Chen    LOG_TRACE << numEvents << " events happended";
359a1e991dSShuo Chen    fillActiveChannels(numEvents, activeChannels);
369a1e991dSShuo Chen  }
379a1e991dSShuo Chen  else if (numEvents == 0)
389a1e991dSShuo Chen  {
399a1e991dSShuo Chen    LOG_TRACE << " nothing happended";
409a1e991dSShuo Chen  }
419a1e991dSShuo Chen  else
429a1e991dSShuo Chen  {
439a1e991dSShuo Chen    LOG_SYSERR << "Poller::poll()";
449a1e991dSShuo Chen  }
459a1e991dSShuo Chen  return now;
469a1e991dSShuo Chen}
479a1e991dSShuo Chen
489a1e991dSShuo Chenvoid Poller::fillActiveChannels(int numEvents,
499a1e991dSShuo Chen                                ChannelList* activeChannels) const
509a1e991dSShuo Chen{
519a1e991dSShuo Chen  for (PollFdList::const_iterator pfd = pollfds_.begin();
529a1e991dSShuo Chen      pfd != pollfds_.end() && numEvents > 0; ++pfd)
539a1e991dSShuo Chen  {
549a1e991dSShuo Chen    if (pfd->revents > 0)
559a1e991dSShuo Chen    {
569a1e991dSShuo Chen      --numEvents;
579a1e991dSShuo Chen      ChannelMap::const_iterator ch = channels_.find(pfd->fd);
589a1e991dSShuo Chen      assert(ch != channels_.end());
599a1e991dSShuo Chen      Channel* channel = ch->second;
609a1e991dSShuo Chen      assert(channel->fd() == pfd->fd);
619a1e991dSShuo Chen      channel->set_revents(pfd->revents);
629a1e991dSShuo Chen      // pfd->revents = 0;
639a1e991dSShuo Chen      activeChannels->push_back(channel);
649a1e991dSShuo Chen    }
659a1e991dSShuo Chen  }
669a1e991dSShuo Chen}
679a1e991dSShuo Chen
689a1e991dSShuo Chenvoid Poller::updateChannel(Channel* channel)
699a1e991dSShuo Chen{
70ee021d99SShuo Chen  assertInLoopThread();
719a1e991dSShuo Chen  LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events();
729a1e991dSShuo Chen  if (channel->index() < 0)
739a1e991dSShuo Chen  {
749a1e991dSShuo Chen    // a new one, add to pollfds_
759a1e991dSShuo Chen    assert(channels_.find(channel->fd()) == channels_.end());
769a1e991dSShuo Chen    struct pollfd pfd;
779a1e991dSShuo Chen    pfd.fd = channel->fd();
789a1e991dSShuo Chen    pfd.events = static_cast<short>(channel->events());
799a1e991dSShuo Chen    pfd.revents = 0;
809a1e991dSShuo Chen    pollfds_.push_back(pfd);
819a1e991dSShuo Chen    int idx = static_cast<int>(pollfds_.size())-1;
829a1e991dSShuo Chen    channel->set_index(idx);
839a1e991dSShuo Chen    channels_[pfd.fd] = channel;
849a1e991dSShuo Chen  }
859a1e991dSShuo Chen  else
869a1e991dSShuo Chen  {
879a1e991dSShuo Chen    // update existing one
889a1e991dSShuo Chen    assert(channels_.find(channel->fd()) != channels_.end());
899a1e991dSShuo Chen    assert(channels_[channel->fd()] == channel);
909a1e991dSShuo Chen    int idx = channel->index();
919a1e991dSShuo Chen    assert(0 <= idx && idx < static_cast<int>(pollfds_.size()));
929a1e991dSShuo Chen    struct pollfd& pfd = pollfds_[idx];
939a1e991dSShuo 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())
979a1e991dSShuo Chen    {
989a1e991dSShuo Chen      // ignore this pollfd
999a1e991dSShuo Chen      pfd.fd = -1;
1009a1e991dSShuo Chen    }
1019a1e991dSShuo Chen  }
1029a1e991dSShuo Chen}
1039a1e991dSShuo Chen
104