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()); 32b4a5ce52SShuo Chen if (numEvents > 0) { 33cc7f415cSShuo Chen LOG_TRACE << numEvents << " events happended"; 34cc7f415cSShuo Chen fillActiveChannels(numEvents, activeChannels); 35b4a5ce52SShuo Chen } else if (numEvents == 0) { 36cc7f415cSShuo Chen LOG_TRACE << " nothing happended"; 37b4a5ce52SShuo Chen } else { 38cc7f415cSShuo Chen LOG_SYSERR << "Poller::poll()"; 39cc7f415cSShuo Chen } 40cc7f415cSShuo Chen return now; 41cc7f415cSShuo Chen} 42cc7f415cSShuo Chen 43cc7f415cSShuo Chenvoid Poller::fillActiveChannels(int numEvents, 44cc7f415cSShuo Chen ChannelList* activeChannels) const 45cc7f415cSShuo Chen{ 46cc7f415cSShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 47cc7f415cSShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 48cc7f415cSShuo Chen { 49cc7f415cSShuo Chen if (pfd->revents > 0) 50cc7f415cSShuo Chen { 51cc7f415cSShuo Chen --numEvents; 52cc7f415cSShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 53cc7f415cSShuo Chen assert(ch != channels_.end()); 54cc7f415cSShuo Chen Channel* channel = ch->second; 55cc7f415cSShuo Chen assert(channel->fd() == pfd->fd); 56cc7f415cSShuo Chen channel->set_revents(pfd->revents); 57cc7f415cSShuo Chen // pfd->revents = 0; 58cc7f415cSShuo Chen activeChannels->push_back(channel); 59cc7f415cSShuo Chen } 60cc7f415cSShuo Chen } 61cc7f415cSShuo Chen} 62cc7f415cSShuo Chen 63cc7f415cSShuo Chenvoid Poller::updateChannel(Channel* channel) 64cc7f415cSShuo Chen{ 65ee021d99SShuo Chen assertInLoopThread(); 66cc7f415cSShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 67b4a5ce52SShuo Chen if (channel->index() < 0) { 68cc7f415cSShuo Chen // a new one, add to pollfds_ 69cc7f415cSShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 70cc7f415cSShuo Chen struct pollfd pfd; 71cc7f415cSShuo Chen pfd.fd = channel->fd(); 72cc7f415cSShuo Chen pfd.events = static_cast<short>(channel->events()); 73cc7f415cSShuo Chen pfd.revents = 0; 74cc7f415cSShuo Chen pollfds_.push_back(pfd); 75cc7f415cSShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 76cc7f415cSShuo Chen channel->set_index(idx); 77cc7f415cSShuo Chen channels_[pfd.fd] = channel; 78b4a5ce52SShuo Chen } else { 79cc7f415cSShuo Chen // update existing one 80cc7f415cSShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 81cc7f415cSShuo Chen assert(channels_[channel->fd()] == channel); 82cc7f415cSShuo Chen int idx = channel->index(); 83cc7f415cSShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 84cc7f415cSShuo Chen struct pollfd& pfd = pollfds_[idx]; 85cc7f415cSShuo Chen assert(pfd.fd == channel->fd() || pfd.fd == -1); 8617c057c3SShuo Chen pfd.events = static_cast<short>(channel->events()); 8717c057c3SShuo Chen pfd.revents = 0; 88b4a5ce52SShuo Chen if (channel->isNoneEvent()) { 89cc7f415cSShuo Chen // ignore this pollfd 90cc7f415cSShuo Chen pfd.fd = -1; 91cc7f415cSShuo Chen } 92cc7f415cSShuo Chen } 93cc7f415cSShuo Chen} 94cc7f415cSShuo Chen 95