Poller.cc revision 17c057c3
19a1e991dSShuo Chen// excerpts from http://code.google.com/p/muduo/ 29a1e991dSShuo Chen// 39a1e991dSShuo Chen// Use of this source code is governed by a BSD-style license 49a1e991dSShuo Chen// that can be found in the License file. 59a1e991dSShuo Chen// 69a1e991dSShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 79a1e991dSShuo Chen 89a1e991dSShuo Chen#include "Poller.h" 99a1e991dSShuo Chen 109a1e991dSShuo Chen#include "Channel.h" 119a1e991dSShuo Chen#include "logging/Logging.h" 129a1e991dSShuo Chen 139a1e991dSShuo Chen#include <assert.h> 149a1e991dSShuo Chen#include <poll.h> 159a1e991dSShuo Chen 169a1e991dSShuo Chenusing namespace muduo; 179a1e991dSShuo Chen 189a1e991dSShuo ChenPoller::Poller(EventLoop* loop) 199a1e991dSShuo Chen : ownerLoop_(loop) 209a1e991dSShuo Chen{ 219a1e991dSShuo Chen} 229a1e991dSShuo Chen 239a1e991dSShuo ChenPoller::~Poller() 249a1e991dSShuo Chen{ 259a1e991dSShuo Chen} 269a1e991dSShuo Chen 279a1e991dSShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels) 289a1e991dSShuo Chen{ 299a1e991dSShuo Chen // XXX pollfds_ shouldn't change 309a1e991dSShuo Chen int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs); 319a1e991dSShuo Chen Timestamp now(Timestamp::now()); 329a1e991dSShuo Chen if (numEvents > 0) 339a1e991dSShuo Chen { 349a1e991dSShuo Chen LOG_TRACE << numEvents << " events happended"; 359a1e991dSShuo Chen fillActiveChannels(numEvents, activeChannels); 369a1e991dSShuo Chen } 379a1e991dSShuo Chen else if (numEvents == 0) 389a1e991dSShuo Chen { 399a1e991dSShuo Chen LOG_TRACE << " nothing happended"; 409a1e991dSShuo Chen } 419a1e991dSShuo Chen else 429a1e991dSShuo Chen { 439a1e991dSShuo Chen LOG_SYSERR << "Poller::poll()"; 449a1e991dSShuo Chen } 459a1e991dSShuo Chen return now; 469a1e991dSShuo Chen} 479a1e991dSShuo Chen 489a1e991dSShuo Chenvoid Poller::fillActiveChannels(int numEvents, 499a1e991dSShuo Chen ChannelList* activeChannels) const 509a1e991dSShuo Chen{ 519a1e991dSShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 529a1e991dSShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 539a1e991dSShuo Chen { 549a1e991dSShuo Chen if (pfd->revents > 0) 559a1e991dSShuo Chen { 569a1e991dSShuo Chen --numEvents; 579a1e991dSShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 589a1e991dSShuo Chen assert(ch != channels_.end()); 599a1e991dSShuo Chen Channel* channel = ch->second; 609a1e991dSShuo Chen assert(channel->fd() == pfd->fd); 619a1e991dSShuo Chen channel->set_revents(pfd->revents); 629a1e991dSShuo Chen // pfd->revents = 0; 639a1e991dSShuo Chen activeChannels->push_back(channel); 649a1e991dSShuo Chen } 659a1e991dSShuo Chen } 669a1e991dSShuo Chen} 679a1e991dSShuo Chen 689a1e991dSShuo Chenvoid Poller::updateChannel(Channel* channel) 699a1e991dSShuo Chen{ 709a1e991dSShuo Chen Poller::assertInLoopThread(); 719a1e991dSShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 729a1e991dSShuo Chen if (channel->index() < 0) 739a1e991dSShuo Chen { 749a1e991dSShuo Chen // a new one, add to pollfds_ 759a1e991dSShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 769a1e991dSShuo Chen struct pollfd pfd; 779a1e991dSShuo Chen pfd.fd = channel->fd(); 789a1e991dSShuo Chen pfd.events = static_cast<short>(channel->events()); 799a1e991dSShuo Chen pfd.revents = 0; 809a1e991dSShuo Chen pollfds_.push_back(pfd); 819a1e991dSShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 829a1e991dSShuo Chen channel->set_index(idx); 839a1e991dSShuo Chen channels_[pfd.fd] = channel; 849a1e991dSShuo Chen } 859a1e991dSShuo Chen else 869a1e991dSShuo Chen { 879a1e991dSShuo Chen // update existing one 889a1e991dSShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 899a1e991dSShuo Chen assert(channels_[channel->fd()] == channel); 909a1e991dSShuo Chen int idx = channel->index(); 919a1e991dSShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 929a1e991dSShuo Chen struct pollfd& pfd = pollfds_[idx]; 939a1e991dSShuo Chen assert(pfd.fd == channel->fd() || pfd.fd == -1); 9417c057c3SShuo Chen pfd.events = static_cast<short>(channel->events()); 9517c057c3SShuo Chen pfd.revents = 0; 960615e80eSShuo Chen if (channel->isNoneEvent()) 979a1e991dSShuo Chen { 989a1e991dSShuo Chen // ignore this pollfd 999a1e991dSShuo Chen pfd.fd = -1; 1009a1e991dSShuo Chen } 1019a1e991dSShuo Chen } 1029a1e991dSShuo Chen} 1039a1e991dSShuo Chen 104