Poller.cc revision 17c057c3
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()); 32cbe8e7d0SShuo Chen if (numEvents > 0) 33cbe8e7d0SShuo Chen { 34cbe8e7d0SShuo Chen LOG_TRACE << numEvents << " events happended"; 35cbe8e7d0SShuo Chen fillActiveChannels(numEvents, activeChannels); 36cbe8e7d0SShuo Chen } 37cbe8e7d0SShuo Chen else if (numEvents == 0) 38cbe8e7d0SShuo Chen { 39cbe8e7d0SShuo Chen LOG_TRACE << " nothing happended"; 40cbe8e7d0SShuo Chen } 41cbe8e7d0SShuo Chen else 42cbe8e7d0SShuo Chen { 43cbe8e7d0SShuo Chen LOG_SYSERR << "Poller::poll()"; 44cbe8e7d0SShuo Chen } 45cbe8e7d0SShuo Chen return now; 46cbe8e7d0SShuo Chen} 47cbe8e7d0SShuo Chen 48cbe8e7d0SShuo Chenvoid Poller::fillActiveChannels(int numEvents, 49cbe8e7d0SShuo Chen ChannelList* activeChannels) const 50cbe8e7d0SShuo Chen{ 51cbe8e7d0SShuo Chen for (PollFdList::const_iterator pfd = pollfds_.begin(); 52cbe8e7d0SShuo Chen pfd != pollfds_.end() && numEvents > 0; ++pfd) 53cbe8e7d0SShuo Chen { 54cbe8e7d0SShuo Chen if (pfd->revents > 0) 55cbe8e7d0SShuo Chen { 56cbe8e7d0SShuo Chen --numEvents; 57cbe8e7d0SShuo Chen ChannelMap::const_iterator ch = channels_.find(pfd->fd); 58cbe8e7d0SShuo Chen assert(ch != channels_.end()); 59cbe8e7d0SShuo Chen Channel* channel = ch->second; 60cbe8e7d0SShuo Chen assert(channel->fd() == pfd->fd); 61cbe8e7d0SShuo Chen channel->set_revents(pfd->revents); 62cbe8e7d0SShuo Chen // pfd->revents = 0; 63cbe8e7d0SShuo Chen activeChannels->push_back(channel); 64cbe8e7d0SShuo Chen } 65cbe8e7d0SShuo Chen } 66cbe8e7d0SShuo Chen} 67cbe8e7d0SShuo Chen 68cbe8e7d0SShuo Chenvoid Poller::updateChannel(Channel* channel) 69cbe8e7d0SShuo Chen{ 70cbe8e7d0SShuo Chen Poller::assertInLoopThread(); 71cbe8e7d0SShuo Chen LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events(); 72cbe8e7d0SShuo Chen if (channel->index() < 0) 73cbe8e7d0SShuo Chen { 74cbe8e7d0SShuo Chen // a new one, add to pollfds_ 75cbe8e7d0SShuo Chen assert(channels_.find(channel->fd()) == channels_.end()); 76cbe8e7d0SShuo Chen struct pollfd pfd; 77cbe8e7d0SShuo Chen pfd.fd = channel->fd(); 78cbe8e7d0SShuo Chen pfd.events = static_cast<short>(channel->events()); 79cbe8e7d0SShuo Chen pfd.revents = 0; 80cbe8e7d0SShuo Chen pollfds_.push_back(pfd); 81cbe8e7d0SShuo Chen int idx = static_cast<int>(pollfds_.size())-1; 82cbe8e7d0SShuo Chen channel->set_index(idx); 83cbe8e7d0SShuo Chen channels_[pfd.fd] = channel; 84cbe8e7d0SShuo Chen } 85cbe8e7d0SShuo Chen else 86cbe8e7d0SShuo Chen { 87cbe8e7d0SShuo Chen // update existing one 88cbe8e7d0SShuo Chen assert(channels_.find(channel->fd()) != channels_.end()); 89cbe8e7d0SShuo Chen assert(channels_[channel->fd()] == channel); 90cbe8e7d0SShuo Chen int idx = channel->index(); 91cbe8e7d0SShuo Chen assert(0 <= idx && idx < static_cast<int>(pollfds_.size())); 92cbe8e7d0SShuo Chen struct pollfd& pfd = pollfds_[idx]; 93cbe8e7d0SShuo 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()) 97cbe8e7d0SShuo Chen { 98cbe8e7d0SShuo Chen // ignore this pollfd 99cbe8e7d0SShuo Chen pfd.fd = -1; 100cbe8e7d0SShuo Chen } 101cbe8e7d0SShuo Chen } 102cbe8e7d0SShuo Chen} 103cbe8e7d0SShuo Chen 104