Poller.cc revision 2745a763
12745a763SShuo Chen// excerpts from http://code.google.com/p/muduo/ 22745a763SShuo Chen// 32745a763SShuo Chen// Use of this source code is governed by a BSD-style license 42745a763SShuo Chen// that can be found in the License file. 52745a763SShuo Chen// 62745a763SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 72745a763SShuo Chen 82745a763SShuo Chen#include "Poller.h" 92745a763SShuo Chen 102745a763SShuo Chen#include "Channel.h" 112745a763SShuo Chen#include "logging/Logging.h" 122745a763SShuo Chen 132745a763SShuo Chen#include <assert.h> 142745a763SShuo Chen#include <poll.h> 152745a763SShuo Chen 162745a763SShuo Chenusing namespace muduo; 172745a763SShuo Chen 182745a763SShuo ChenPoller::Poller(EventLoop* loop) 192745a763SShuo Chen : ownerLoop_(loop) 202745a763SShuo Chen{ 212745a763SShuo Chen} 222745a763SShuo Chen 232745a763SShuo ChenPoller::~Poller() 242745a763SShuo Chen{ 252745a763SShuo Chen} 262745a763SShuo Chen 272745a763SShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels) 282745a763SShuo Chen{ 292745a763SShuo Chen // XXX pollfds_ shouldn't change 302745a763SShuo Chen int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs); 312745a763SShuo Chen Timestamp now(Timestamp::now()); 322745a763SShuo Chen if (numEvents > 0) 332745a763SShuo Chen { 342745a763SShuo Chen LOG_TRACE << numEvents << " events happended"; 352745a763SShuo Chen fillActiveChannels(numEvents, activeChannels); 362745a763SShuo Chen } 372745a763SShuo Chen else if (numEvents == 0) 382745a763SShuo Chen { 392745a763SShuo Chen LOG_TRACE << " nothing happended"; 402745a763SShuo Chen } 412745a763SShuo Chen else 422745a763SShuo Chen { 432745a763SShuo Chen LOG_SYSERR << "Poller::poll()"; 442745a763SShuo Chen } 452745a763SShuo Chen return now; 462745a763SShuo Chen} 472745a763SShuo Chen 482745a763SShuo Chenvoid Poller::fillActiveChannels(int numEvents, 492745a763SShuo Chen ChannelList* activeChannels) const 502745a763SShuo Chen{ 512745a763SShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 522745a763SShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 532745a763SShuo Chen { 542745a763SShuo Chen if (pfd->revents > 0) 552745a763SShuo Chen { 562745a763SShuo Chen --numEvents; 572745a763SShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 582745a763SShuo Chen assert(ch != channels_.end()); 592745a763SShuo Chen Channel* channel = ch->second; 602745a763SShuo Chen assert(channel->fd() == pfd->fd); 612745a763SShuo Chen channel->set_revents(pfd->revents); 622745a763SShuo Chen // pfd->revents = 0; 632745a763SShuo Chen activeChannels->push_back(channel); 642745a763SShuo Chen } 652745a763SShuo Chen } 662745a763SShuo Chen} 672745a763SShuo Chen 682745a763SShuo Chenvoid Poller::updateChannel(Channel* channel) 692745a763SShuo Chen{ 702745a763SShuo Chen Poller::assertInLoopThread(); 712745a763SShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 722745a763SShuo Chen if (channel->index() < 0) 732745a763SShuo Chen { 742745a763SShuo Chen // a new one, add to pollfds_ 752745a763SShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 762745a763SShuo Chen struct pollfd pfd; 772745a763SShuo Chen pfd.fd = channel->fd(); 782745a763SShuo Chen pfd.events = static_cast<short>(channel->events()); 792745a763SShuo Chen pfd.revents = 0; 802745a763SShuo Chen pollfds_.push_back(pfd); 812745a763SShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 822745a763SShuo Chen channel->set_index(idx); 832745a763SShuo Chen channels_[pfd.fd] = channel; 842745a763SShuo Chen } 852745a763SShuo Chen else 862745a763SShuo Chen { 872745a763SShuo Chen // update existing one 882745a763SShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 892745a763SShuo Chen assert(channels_[channel->fd()] == channel); 902745a763SShuo Chen int idx = channel->index(); 912745a763SShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 922745a763SShuo Chen struct pollfd& pfd = pollfds_[idx]; 932745a763SShuo Chen assert(pfd.fd == channel->fd() || pfd.fd == -1); 942745a763SShuo Chen pfd.events = static_cast<short>(channel->events()); 952745a763SShuo Chen if (pfd.events == Channel::kNoneEvent) 962745a763SShuo Chen { 972745a763SShuo Chen // ignore this pollfd 982745a763SShuo Chen pfd.fd = -1; 992745a763SShuo Chen } 1002745a763SShuo Chen } 1012745a763SShuo Chen} 1022745a763SShuo Chen 103