14b7a333eSShuo Chen// excerpts from http://code.google.com/p/muduo/ 24b7a333eSShuo Chen// 34b7a333eSShuo Chen// Use of this source code is governed by a BSD-style license 44b7a333eSShuo Chen// that can be found in the License file. 54b7a333eSShuo Chen// 64b7a333eSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 74b7a333eSShuo Chen 84b7a333eSShuo Chen#include "Poller.h" 94b7a333eSShuo Chen 104b7a333eSShuo Chen#include "Channel.h" 114b7a333eSShuo Chen#include "logging/Logging.h" 124b7a333eSShuo Chen 134b7a333eSShuo Chen#include <assert.h> 144b7a333eSShuo Chen#include <poll.h> 154b7a333eSShuo Chen 164b7a333eSShuo Chenusing namespace muduo; 174b7a333eSShuo Chen 184b7a333eSShuo ChenPoller::Poller(EventLoop* loop) 194b7a333eSShuo Chen : ownerLoop_(loop) 204b7a333eSShuo Chen{ 214b7a333eSShuo Chen} 224b7a333eSShuo Chen 234b7a333eSShuo ChenPoller::~Poller() 244b7a333eSShuo Chen{ 254b7a333eSShuo Chen} 264b7a333eSShuo Chen 274b7a333eSShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels) 284b7a333eSShuo Chen{ 294b7a333eSShuo Chen // XXX pollfds_ shouldn't change 304b7a333eSShuo Chen int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs); 314b7a333eSShuo Chen Timestamp now(Timestamp::now()); 32b4a5ce52SShuo Chen if (numEvents > 0) { 334b7a333eSShuo Chen LOG_TRACE << numEvents << " events happended"; 344b7a333eSShuo Chen fillActiveChannels(numEvents, activeChannels); 35b4a5ce52SShuo Chen } else if (numEvents == 0) { 364b7a333eSShuo Chen LOG_TRACE << " nothing happended"; 37b4a5ce52SShuo Chen } else { 384b7a333eSShuo Chen LOG_SYSERR << "Poller::poll()"; 394b7a333eSShuo Chen } 404b7a333eSShuo Chen return now; 414b7a333eSShuo Chen} 424b7a333eSShuo Chen 434b7a333eSShuo Chenvoid Poller::fillActiveChannels(int numEvents, 444b7a333eSShuo Chen ChannelList* activeChannels) const 454b7a333eSShuo Chen{ 464b7a333eSShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 474b7a333eSShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 484b7a333eSShuo Chen { 494b7a333eSShuo Chen if (pfd->revents > 0) 504b7a333eSShuo Chen { 514b7a333eSShuo Chen --numEvents; 524b7a333eSShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 534b7a333eSShuo Chen assert(ch != channels_.end()); 544b7a333eSShuo Chen Channel* channel = ch->second; 554b7a333eSShuo Chen assert(channel->fd() == pfd->fd); 564b7a333eSShuo Chen channel->set_revents(pfd->revents); 574b7a333eSShuo Chen // pfd->revents = 0; 584b7a333eSShuo Chen activeChannels->push_back(channel); 594b7a333eSShuo Chen } 604b7a333eSShuo Chen } 614b7a333eSShuo Chen} 624b7a333eSShuo Chen 634b7a333eSShuo Chenvoid Poller::updateChannel(Channel* channel) 644b7a333eSShuo Chen{ 65ee021d99SShuo Chen assertInLoopThread(); 664b7a333eSShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 67b4a5ce52SShuo Chen if (channel->index() < 0) { 684b7a333eSShuo Chen // a new one, add to pollfds_ 694b7a333eSShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 704b7a333eSShuo Chen struct pollfd pfd; 714b7a333eSShuo Chen pfd.fd = channel->fd(); 724b7a333eSShuo Chen pfd.events = static_cast<short>(channel->events()); 734b7a333eSShuo Chen pfd.revents = 0; 744b7a333eSShuo Chen pollfds_.push_back(pfd); 754b7a333eSShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 764b7a333eSShuo Chen channel->set_index(idx); 774b7a333eSShuo Chen channels_[pfd.fd] = channel; 78b4a5ce52SShuo Chen } else { 794b7a333eSShuo Chen // update existing one 804b7a333eSShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 814b7a333eSShuo Chen assert(channels_[channel->fd()] == channel); 824b7a333eSShuo Chen int idx = channel->index(); 834b7a333eSShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 844b7a333eSShuo Chen struct pollfd& pfd = pollfds_[idx]; 854792573fSShuo 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()) { 894b7a333eSShuo Chen // ignore this pollfd 904792573fSShuo Chen pfd.fd = -1; 914b7a333eSShuo Chen } 924b7a333eSShuo Chen } 934b7a333eSShuo Chen} 944b7a333eSShuo Chen 95