Poller.cc revision b4a5ce52
1cbe8e7d0SShuo Chen// excerpts from http://code.google.com/p/muduo/ 2cbe8e7d0SShuo Chen// 3cbe8e7d0SShuo Chen// Use of this source code is governed by a BSD-style license 4cbe8e7d0SShuo Chen// that can be found in the License file. 5cbe8e7d0SShuo Chen// 6cbe8e7d0SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 7cbe8e7d0SShuo Chen 8cbe8e7d0SShuo Chen#include "Poller.h" 9cbe8e7d0SShuo Chen 10cbe8e7d0SShuo Chen#include "Channel.h" 11cbe8e7d0SShuo Chen#include "logging/Logging.h" 12cbe8e7d0SShuo Chen 13cbe8e7d0SShuo Chen#include <assert.h> 14cbe8e7d0SShuo Chen#include <poll.h> 15cbe8e7d0SShuo Chen 16cbe8e7d0SShuo Chenusing namespace muduo; 17cbe8e7d0SShuo Chen 18cbe8e7d0SShuo ChenPoller::Poller(EventLoop* loop) 19cbe8e7d0SShuo Chen : ownerLoop_(loop) 20cbe8e7d0SShuo Chen{ 21cbe8e7d0SShuo Chen} 22cbe8e7d0SShuo Chen 23cbe8e7d0SShuo ChenPoller::~Poller() 24cbe8e7d0SShuo Chen{ 25cbe8e7d0SShuo Chen} 26cbe8e7d0SShuo Chen 27cbe8e7d0SShuo ChenTimestamp Poller::poll(int timeoutMs, ChannelList* activeChannels) 28cbe8e7d0SShuo Chen{ 29cbe8e7d0SShuo Chen // XXX pollfds_ shouldn't change 30cbe8e7d0SShuo Chen int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs); 31cbe8e7d0SShuo Chen Timestamp now(Timestamp::now()); 32b4a5ce52SShuo Chen if (numEvents > 0) { 33cbe8e7d0SShuo Chen LOG_TRACE << numEvents << " events happended"; 34cbe8e7d0SShuo Chen fillActiveChannels(numEvents, activeChannels); 35b4a5ce52SShuo Chen } else if (numEvents == 0) { 36cbe8e7d0SShuo Chen LOG_TRACE << " nothing happended"; 37b4a5ce52SShuo Chen } else { 38cbe8e7d0SShuo Chen LOG_SYSERR << "Poller::poll()"; 39cbe8e7d0SShuo Chen } 40cbe8e7d0SShuo Chen return now; 41cbe8e7d0SShuo Chen} 42cbe8e7d0SShuo Chen 43cbe8e7d0SShuo Chenvoid Poller::fillActiveChannels(int numEvents, 44cbe8e7d0SShuo Chen ChannelList* activeChannels) const 45cbe8e7d0SShuo Chen{ 46cbe8e7d0SShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 47cbe8e7d0SShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 48cbe8e7d0SShuo Chen { 49cbe8e7d0SShuo Chen if (pfd->revents > 0) 50cbe8e7d0SShuo Chen { 51cbe8e7d0SShuo Chen --numEvents; 52cbe8e7d0SShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 53cbe8e7d0SShuo Chen assert(ch != channels_.end()); 54cbe8e7d0SShuo Chen Channel* channel = ch->second; 55cbe8e7d0SShuo Chen assert(channel->fd() == pfd->fd); 56cbe8e7d0SShuo Chen channel->set_revents(pfd->revents); 57cbe8e7d0SShuo Chen // pfd->revents = 0; 58cbe8e7d0SShuo Chen activeChannels->push_back(channel); 59cbe8e7d0SShuo Chen } 60cbe8e7d0SShuo Chen } 61cbe8e7d0SShuo Chen} 62cbe8e7d0SShuo Chen 63cbe8e7d0SShuo Chenvoid Poller::updateChannel(Channel* channel) 64cbe8e7d0SShuo Chen{ 65ee021d99SShuo Chen assertInLoopThread(); 66cbe8e7d0SShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 67b4a5ce52SShuo Chen if (channel->index() < 0) { 68cbe8e7d0SShuo Chen // a new one, add to pollfds_ 69cbe8e7d0SShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 70cbe8e7d0SShuo Chen struct pollfd pfd; 71cbe8e7d0SShuo Chen pfd.fd = channel->fd(); 72cbe8e7d0SShuo Chen pfd.events = static_cast<short>(channel->events()); 73cbe8e7d0SShuo Chen pfd.revents = 0; 74cbe8e7d0SShuo Chen pollfds_.push_back(pfd); 75cbe8e7d0SShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 76cbe8e7d0SShuo Chen channel->set_index(idx); 77cbe8e7d0SShuo Chen channels_[pfd.fd] = channel; 78b4a5ce52SShuo Chen } else { 79cbe8e7d0SShuo Chen // update existing one 80cbe8e7d0SShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 81cbe8e7d0SShuo Chen assert(channels_[channel->fd()] == channel); 82cbe8e7d0SShuo Chen int idx = channel->index(); 83cbe8e7d0SShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 84cbe8e7d0SShuo Chen struct pollfd& pfd = pollfds_[idx]; 85cbe8e7d0SShuo 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()) { 89cbe8e7d0SShuo Chen // ignore this pollfd 90cbe8e7d0SShuo Chen pfd.fd = -1; 91cbe8e7d0SShuo Chen } 92cbe8e7d0SShuo Chen } 93cbe8e7d0SShuo Chen} 94cbe8e7d0SShuo Chen 95