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