Poller.cc revision 4792573f
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()); 324b7a333eSShuo Chen if (numEvents > 0) 334b7a333eSShuo Chen { 344b7a333eSShuo Chen LOG_TRACE << numEvents << " events happended"; 354b7a333eSShuo Chen fillActiveChannels(numEvents, activeChannels); 364b7a333eSShuo Chen } 374b7a333eSShuo Chen else if (numEvents == 0) 384b7a333eSShuo Chen { 394b7a333eSShuo Chen LOG_TRACE << " nothing happended"; 404b7a333eSShuo Chen } 414b7a333eSShuo Chen else 424b7a333eSShuo Chen { 434b7a333eSShuo Chen LOG_SYSERR << "Poller::poll()"; 444b7a333eSShuo Chen } 454b7a333eSShuo Chen return now; 464b7a333eSShuo Chen} 474b7a333eSShuo Chen 484b7a333eSShuo Chenvoid Poller::fillActiveChannels(int numEvents, 494b7a333eSShuo Chen ChannelList* activeChannels) const 504b7a333eSShuo Chen{ 514b7a333eSShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 524b7a333eSShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 534b7a333eSShuo Chen { 544b7a333eSShuo Chen if (pfd->revents > 0) 554b7a333eSShuo Chen { 564b7a333eSShuo Chen --numEvents; 574b7a333eSShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 584b7a333eSShuo Chen assert(ch != channels_.end()); 594b7a333eSShuo Chen Channel* channel = ch->second; 604b7a333eSShuo Chen assert(channel->fd() == pfd->fd); 614b7a333eSShuo Chen channel->set_revents(pfd->revents); 624b7a333eSShuo Chen // pfd->revents = 0; 634b7a333eSShuo Chen activeChannels->push_back(channel); 644b7a333eSShuo Chen } 654b7a333eSShuo Chen } 664b7a333eSShuo Chen} 674b7a333eSShuo Chen 684b7a333eSShuo Chenvoid Poller::updateChannel(Channel* channel) 694b7a333eSShuo Chen{ 704b7a333eSShuo Chen Poller::assertInLoopThread(); 714b7a333eSShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 724b7a333eSShuo Chen if (channel->index() < 0) 734b7a333eSShuo Chen { 744b7a333eSShuo Chen // a new one, add to pollfds_ 754b7a333eSShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 764b7a333eSShuo Chen struct pollfd pfd; 774b7a333eSShuo Chen pfd.fd = channel->fd(); 784b7a333eSShuo Chen pfd.events = static_cast<short>(channel->events()); 794b7a333eSShuo Chen pfd.revents = 0; 804b7a333eSShuo Chen pollfds_.push_back(pfd); 814b7a333eSShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 824b7a333eSShuo Chen channel->set_index(idx); 834b7a333eSShuo Chen channels_[pfd.fd] = channel; 844b7a333eSShuo Chen } 854b7a333eSShuo Chen else 864b7a333eSShuo Chen { 874b7a333eSShuo Chen // update existing one 884b7a333eSShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 894b7a333eSShuo Chen assert(channels_[channel->fd()] == channel); 904b7a333eSShuo Chen int idx = channel->index(); 914b7a333eSShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 924b7a333eSShuo Chen struct pollfd& pfd = pollfds_[idx]; 934792573fSShuo Chen assert(pfd.fd == channel->fd() || pfd.fd == -1); 944b7a333eSShuo Chen pfd.events = static_cast<short>(channel->events()); 954b7a333eSShuo Chen if (pfd.events == Channel::kNoneEvent) 964b7a333eSShuo Chen { 974b7a333eSShuo Chen // ignore this pollfd 984792573fSShuo Chen pfd.fd = -1; 994b7a333eSShuo Chen } 1004b7a333eSShuo Chen } 1014b7a333eSShuo Chen} 1024b7a333eSShuo Chen 103