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()); 32b4a5ce52SShuo Chen if (numEvents > 0) { 339a1e991dSShuo Chen LOG_TRACE << numEvents << " events happended"; 349a1e991dSShuo Chen fillActiveChannels(numEvents, activeChannels); 35b4a5ce52SShuo Chen } else if (numEvents == 0) { 369a1e991dSShuo Chen LOG_TRACE << " nothing happended"; 37b4a5ce52SShuo Chen } else { 389a1e991dSShuo Chen LOG_SYSERR << "Poller::poll()"; 399a1e991dSShuo Chen } 409a1e991dSShuo Chen return now; 419a1e991dSShuo Chen} 429a1e991dSShuo Chen 439a1e991dSShuo Chenvoid Poller::fillActiveChannels(int numEvents, 449a1e991dSShuo Chen ChannelList* activeChannels) const 459a1e991dSShuo Chen{ 469a1e991dSShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 479a1e991dSShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 489a1e991dSShuo Chen { 499a1e991dSShuo Chen if (pfd->revents > 0) 509a1e991dSShuo Chen { 519a1e991dSShuo Chen --numEvents; 529a1e991dSShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 539a1e991dSShuo Chen assert(ch != channels_.end()); 549a1e991dSShuo Chen Channel* channel = ch->second; 559a1e991dSShuo Chen assert(channel->fd() == pfd->fd); 569a1e991dSShuo Chen channel->set_revents(pfd->revents); 579a1e991dSShuo Chen // pfd->revents = 0; 589a1e991dSShuo Chen activeChannels->push_back(channel); 599a1e991dSShuo Chen } 609a1e991dSShuo Chen } 619a1e991dSShuo Chen} 629a1e991dSShuo Chen 639a1e991dSShuo Chenvoid Poller::updateChannel(Channel* channel) 649a1e991dSShuo Chen{ 65ee021d99SShuo Chen assertInLoopThread(); 669a1e991dSShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 67b4a5ce52SShuo Chen if (channel->index() < 0) { 689a1e991dSShuo Chen // a new one, add to pollfds_ 699a1e991dSShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 709a1e991dSShuo Chen struct pollfd pfd; 719a1e991dSShuo Chen pfd.fd = channel->fd(); 729a1e991dSShuo Chen pfd.events = static_cast<short>(channel->events()); 739a1e991dSShuo Chen pfd.revents = 0; 749a1e991dSShuo Chen pollfds_.push_back(pfd); 759a1e991dSShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 769a1e991dSShuo Chen channel->set_index(idx); 779a1e991dSShuo Chen channels_[pfd.fd] = channel; 78b4a5ce52SShuo Chen } else { 799a1e991dSShuo Chen // update existing one 809a1e991dSShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 819a1e991dSShuo Chen assert(channels_[channel->fd()] == channel); 829a1e991dSShuo Chen int idx = channel->index(); 839a1e991dSShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 849a1e991dSShuo Chen struct pollfd& pfd = pollfds_[idx]; 859a1e991dSShuo 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()) { 899a1e991dSShuo Chen // ignore this pollfd 909a1e991dSShuo Chen pfd.fd = -1; 919a1e991dSShuo Chen } 929a1e991dSShuo Chen } 939a1e991dSShuo Chen} 949a1e991dSShuo Chen 95