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