1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_TOOLS_FLIP_SERVER_EPOLL_SERVER_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_TOOLS_FLIP_SERVER_EPOLL_SERVER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fcntl.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/queue.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <ext/hash_map> // it is annoying that gcc does this. oh well. 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <ext/hash_set> 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <map> 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <utility> 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <set> 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector> 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// #define EPOLL_SERVER_EVENT_TRACING 1 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Defining EPOLL_SERVER_EVENT_TRACING 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// causes code to exist which didn't before. 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This code tracks each event generated by the epollserver, 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// as well as providing a per-fd-registered summary of 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// events. Note that enabling this code vastly slows 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// down operations, and uses substantially more 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// memory. For these reasons, it should only be enabled when doing 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// developer debugging at his/her workstation. 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A structure called 'EventRecorder' will exist when 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the macro is defined. See the EventRecorder class interface 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// within the EpollServer class for more details. 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EPOLL_SERVER_EVENT_TRACING 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <iostream> 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/epoll.h> 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass EpollServer; 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass EpollAlarmCallbackInterface; 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ReadPipeCallback; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct EpollEvent { 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollEvent(int events, bool is_epoll_wait) 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : in_events(events), 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out_ready_mask(0) { 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int in_events; // incoming events 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int out_ready_mask; // the new event mask for ready list (0 means don't 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // get on the ready list). This field is always 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // initialized to 0 when the event is passed to 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnEvent. 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Callbacks which go into EpollServers are expected to derive from this class. 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass EpollCallbackInterface { 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the callback is registered into a EpollServer. 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // eps - the poll server into which this callback was registered 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor which was registered 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc) 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which was registered (and will initially be used 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the epoll() calls) 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) = 0; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the event_mask is modified (for a file-descriptor) 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor which was registered 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc) 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which was is now curren (and will be used 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in subsequent epoll() calls) 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnModification(int fd, int event_mask) = 0; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called whenever an event occurs on the file-descriptor. 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This is where the bulk of processing is expected to occur. 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor which was registered 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event - a struct that contains the event mask (composed of EPOLLIN, 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // EPOLLOUT, etc), a flag that indicates whether this is a true 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_wait event vs one from the ready list, and an output 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // parameter for OnEvent to inform the EpollServer whether to put 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this fd on the ready list. 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnEvent(int fd, EpollEvent* event) = 0; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the file-descriptor is unregistered from the poll-server. 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor which was registered, and of this call, is now 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // unregistered. 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // replaced - If true, this callback is being replaced by another, otherwise 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it is simply being removed. 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnUnregistration(int fd, bool replaced) = 0; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the epoll server is shutting down. This is different from 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnUnregistration because the subclass may want to clean up memory. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This is called in leiu of OnUnregistration. 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor which was registered. 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnShutdown(EpollServer* eps, int fd) = 0; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~EpollCallbackInterface() {} 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollCallbackInterface() {} 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//////////////////////////////////////////////////////////////////////////////// 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//////////////////////////////////////////////////////////////////////////////// 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass EpollServer { 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef EpollAlarmCallbackInterface AlarmCB; 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef EpollCallbackInterface CB; 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::multimap<int64, AlarmCB*> TimeToAlarmCBMap; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef TimeToAlarmCBMap::iterator AlarmRegToken; 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Constructor: 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // By default, we don't wait any amount of time for events, and 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we suggest to the epoll-system that we're going to use on-the-order 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of 1024 FDs. 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollServer(); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Destructor 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~EpollServer(); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Register a callback to be called whenever an event contained 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the set of events included in event_mask occurs on the 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // file-descriptor 'fd' 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that only one callback is allowed to be registered for 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // any specific file-decriptor. 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If a callback is registered for a file-descriptor which has already 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // been registered, then the previous callback is unregistered with 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the 'replaced' flag set to true. I.e. the previous callback's 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnUnregistration() function is called like so: 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnUnregistration(fd, true); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The epoll server does NOT take on ownership of the callback: the callback 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // creator is responsible for managing that memory. 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - a valid file-descriptor 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cb - an instance of a subclass of EpollCallbackInterface 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the events for which the callback would like to be 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // called. 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RegisterFD(int fd, CB* cb, int event_mask); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A shortcut for RegisterFD which sets things up such that the 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // callback is called when 'fd' is available for writing. 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - a valid file-descriptor 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cb - an instance of a subclass of EpollCallbackInterface 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RegisterFDForWrite(int fd, CB* cb); 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A shortcut for RegisterFD which sets things up such that the 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // callback is called when 'fd' is available for reading or writing. 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - a valid file-descriptor 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cb - an instance of a subclass of EpollCallbackInterface 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RegisterFDForReadWrite(int fd, CB* cb); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A shortcut for RegisterFD which sets things up such that the 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // callback is called when 'fd' is available for reading. 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - a valid file-descriptor 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cb - an instance of a subclass of EpollCallbackInterface 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RegisterFDForRead(int fd, CB* cb); 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Removes the FD and the associated callback from the pollserver. 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the callback is registered with other FDs, they will continue 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to be processed using the callback without modification. 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file-descriptor which should no-longer be monitored. 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void UnregisterFD(int fd); 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modifies the event mask for the file-descriptor, replacing 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the old event_mask with the new one specified here. 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the fd whose event mask should be modified. 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - the new event mask. 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void ModifyCallback(int fd, int event_mask); 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modifies the event mask for the file-descriptor such that we 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no longer request events when 'fd' is readable. 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the fd whose event mask should be modified. 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void StopRead(int fd); 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modifies the event mask for the file-descriptor such that we 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request events when 'fd' is readable. 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the fd whose event mask should be modified. 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void StartRead(int fd); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modifies the event mask for the file-descriptor such that we 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no longer request events when 'fd' is writable. 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the fd whose event mask should be modified. 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void StopWrite(int fd); 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modifies the event mask for the file-descriptor such that we 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request events when 'fd' is writable. 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the fd whose event mask should be modified. 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void StartWrite(int fd); 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Looks up the callback associated with the file-desriptor 'fd'. 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If a callback is associated with this file-descriptor, then 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it's OnEvent() method is called with the file-descriptor 'fd', 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // and event_mask 'event_mask' 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If no callback is registered for this file-descriptor, nothing 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // will happen as a result of this call. 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This function is used internally by the EpollServer, but is 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // available publically so that events might be 'faked'. Calling 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this function with an fd and event_mask is equivalent (as far 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // as the callback is concerned) to having a real event generated 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // by epoll (except, of course, that read(), etc won't necessarily 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be able to read anything) 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file-descriptor on which an event has occured. 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - a bitmask representing the events which have occured 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on/for this fd. This bitmask is composed of 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // POLLIN, POLLOUT, etc. 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void HandleEvent(int fd, int event_mask); 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Call this when you want the pollserver to 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // wait for events and execute the callbacks associated with 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the file-descriptors on which those events have occured. 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Depending on the value of timeout_in_us_, this may or may 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // not return immediately. Please reference the set_timeout() 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // function for the specific behaviour. 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void WaitForEventsAndExecuteCallbacks(); 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // When an fd is registered to use edge trigger notification, the ready 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // list can be used to simulate level trigger semantics. Edge trigger 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // registration doesn't send an initial event, and only rising edge (going 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from blocked to unblocked) events are sent. A callback can put itself on 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the ready list by calling SetFDReady() after calling RegisterFD(). The 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnEvent method of all callbacks associated with the fds on the ready 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // list will be called immediately after processing the events returned by 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_wait(). The fd is removed from the ready list before the 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // callback's OnEvent() method is invoked. To stay on the ready list, the 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnEvent() (or some function in that call chain) must call SetFDReady 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // again. When a fd is unregistered using UnregisterFD(), the fd is 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // automatically removed from the ready list. 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // When the callback for a edge triggered fd hits the falling edge (about 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to block, either because of it got an EAGAIN, or had a short read/write 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // operation), it should remove itself from the ready list using 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // SetFDNotReady() (since OnEvent cannot distinguish between invocation 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from the ready list vs from a normal epoll event). All four ready list 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // methods are safe to be called within the context of the callbacks. 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since the ready list invokes EpollCallbackInterface::OnEvent, only fds 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that are registered with the EpollServer will be put on the ready list. 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // SetFDReady() and SetFDNotReady() will do nothing if the EpollServer 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // doesn't know about the fd passed in. 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since the ready list cannot reliably determine proper set of events 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which should be sent to the callback, SetFDReady() requests the caller 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to provide the ready list with the event mask, which will be used later 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // when OnEvent() is invoked by the ready list. Hence, the event_mask 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // passedto SetFDReady() does not affect the actual epoll registration of 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the fd with the kernel. If a fd is already put on the ready list, and 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // SetFDReady() is called again for that fd with a different event_mask, 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the event_mask will be updated. 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void SetFDReady(int fd, int events_to_fake); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void SetFDNotReady(int fd); 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // debugging tools and for writing unit tests. 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ISFDReady() returns whether a fd is in the ready list. 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ReadyListSize() returns the number of fds on the ready list. 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // VerifyReadyList() checks the consistency of internal data structure. It 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // will CHECK if it finds an error. 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool IsFDReady(int fd) const; 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t ReadyListSize() const { return ready_list_size_; } 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void VerifyReadyList() const; 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Registers an alarm 'ac' to go off at time 'timeout_time_in_us'. 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the callback returns a positive number from its OnAlarm() function, 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // then the callback will be re-registered at that time, else the alarm 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // owner is responsible for freeing up memory. 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Important: A give AlarmCB* can not be registered again if it is already 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // registered. If a user wants to register a callback again it should first 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // unregister the previous callback before calling RegisterAlarm again. 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // timeout_time_in_us - the absolute time at which the alarm should go off 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ac - the alarm which will be called. 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RegisterAlarm(int64 timeout_time_in_us, AlarmCB* ac); 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() + 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // delta_in_us). While this is somewhat less accurate (see the description 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // for ApproximateNowInUs() to see how 'approximate'), the error is never 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // worse than the amount of time it takes to process all events in one 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEvents. As with 'RegisterAlarm()', if the callback returns a 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // positive number from its OnAlarm() function, then the callback will be 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // re-registered at that time, else the alarm owner is responsible for 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // freeing up memory. 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that this function is purely a convienence. The 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // same thing may be accomplished by using RegisterAlarm with 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ApproximateNowInUs() directly. 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Important: A give AlarmCB* can not be registered again if it is already 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // registered. If a user wants to register a callback again it should first 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // unregister the previous callback before calling RegisterAlarm again. 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which point the alarm should go off. 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ac - the alarm which will be called. 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RegisterAlarmApproximateDelta(int64 delta_in_us, AlarmCB* ac) { 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac); 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Unregister the alarm referred to by iterator_token; Callers should 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be warned that a token may have become already invalid when OnAlarm() 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is called, was unregistered, or OnShutdown was called on that alarm. 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // iterator_token - iterator to the alarm callback to unregister. 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void UnregisterAlarm( 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const EpollServer::AlarmRegToken& iterator_token); 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns the number of file-descriptors registered in this EpollServer. 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns: 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // number of FDs registered (discounting the internal pipe used for Wake) 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int NumFDsRegistered() const; 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Force the epoll server to wake up (by writing to an internal pipe). 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Wake(); 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Wrapper around WallTimer's NowInUsec. We do this so that we can test 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // EpollServer without using the system clock (and can avoid the flakiness 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that would ensue) 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns: 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the current time as number of microseconds since the Unix epoch. 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int64 NowInUsec() const; 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Since calling NowInUsec() many thousands of times per 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks function call is, to say the least, 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // inefficient, we allow users to use an approximate time instead. The 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // time returned from this function is as accurate as NowInUsec() when 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // callstack. 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this function returns the time at which the 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks function started to process events or 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // alarms. 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Essentially, this function makes available a fast and mostly accurate 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // mechanism for getting the time for any function handling an event or 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // alarm. When functions which are not handling callbacks or alarms call 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this function, they get the slow and "absolutely" accurate time. 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Users should be encouraged to use this function. 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns: 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the "approximate" current time as number of microseconds since the Unix 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoch. 44372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int64 ApproximateNowInUsec() const; 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static std::string EventMaskToString(int event_mask); 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Logs the state of the epoll server with LOG(ERROR). 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void LogStateOnCrash(); 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Set the timeout to the value specified. 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the timeout is set to a negative number, 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks() will only return when an event has 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // occured 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the timeout is set to zero, 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks() will return immediately 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the timeout is set to a positive number, 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks() will return when an event has 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // occured, or when timeout_in_us microseconds has elapsed, whichever 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is first. 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // timeout_in_us - value specified depending on behaviour desired. 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // See above. 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_timeout_in_us(int64 timeout_in_us) { 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timeout_in_us_ = timeout_in_us; 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Accessor for the current value of timeout_in_us. 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int timeout_in_us() const { return timeout_in_us_; } 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true when the EpollServer() is being destroyed. 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool in_shutdown() const { return in_shutdown_; } 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ContainsAlarm(EpollAlarmCallbackInterface* alarm) const { 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return all_alarms_.find(alarm) != all_alarms_.end(); 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A function for implementing the ready list. It invokes OnEvent for each 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of the fd in the ready list, and takes care of adding them back to the 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ready list if the callback requests it (by checking that out_ready_mask 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is non-zero). 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CallReadyListCallbacks(); 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Granularity at which time moves when considering what alarms are on. 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // See function: DoRoundingOnNow() on exact usage. 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const int kMinimumEffectiveAlarmQuantum; 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int GetFlags(int fd); 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott inline int SetFlags(int fd, int flags) { 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return fcntl(fd, F_SETFL, flags | O_NONBLOCK); 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void SetNonblocking(int fd); 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This exists here so that we can override this function in unittests 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in order to make effective mock EpollServer objects. 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int epoll_wait_impl(int epfd, 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct epoll_event* events, 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int max_events, 50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int timeout_in_ms); 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this struct is used internally, and is never used by anything external 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to this class. Some of its members are declared mutable to get around the 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // restriction imposed by hash_set. Since hash_set knows nothing about the 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // objects it stores, it has to assume that every bit of the object is used 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in the hash function and equal_to comparison. Thus hash_set::iterator is a 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // const iterator. In this case, the only thing that must stay constant is 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd. Everything else are just along for the ride and changing them doesn't 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // compromise the hash_set integrity. 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct CBAndEventMask { 518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CBAndEventMask() 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : cb(NULL), 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd(-1), 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_mask(0), 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events_asserted(0), 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events_to_fake(0), 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott in_use(false) { 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry.le_next = NULL; 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry.le_prev = NULL; 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CBAndEventMask(EpollCallbackInterface* cb, 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int event_mask, 531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd) 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : cb(cb), fd(fd), event_mask(event_mask), events_asserted(0), 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events_to_fake(0), in_use(false) { 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry.le_next = NULL; 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry.le_prev = NULL; 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Required operator for hash_set. Normally operator== should be a free 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // standing function. However, since CBAndEventMask is a protected type and 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it will never be a base class, it makes no difference. 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(const CBAndEventMask& cb_and_mask) const { 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return fd == cb_and_mask.fd; 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A callback. If the fd is unregistered inside the callchain of OnEvent, 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the cb will be set to NULL. 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable EpollCallbackInterface* cb; 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable LIST_ENTRY(CBAndEventMask) entry; 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // file descriptor registered with the epoll server. 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the current event_mask registered for this callback. 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable int event_mask; 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the event_mask that was returned by epoll 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable int events_asserted; 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the event_mask for the ready list to use to call OnEvent. 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable int events_to_fake; 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // toggle around calls to OnEvent to tell UnregisterFD to not erase the 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // iterator because HandleEvent is using it. 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable bool in_use; 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Custom hash function to be used by hash_set. 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct CBAndEventMaskHash { 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t operator()(const CBAndEventMask& cb_and_eventmask) const { 565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return static_cast<size_t>(cb_and_eventmask.fd); 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef __gnu_cxx::hash_set<CBAndEventMask, CBAndEventMaskHash> FDToCBMap; 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the following four functions are OS-specific, and are likely 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to be changed in a subclass if the poll/select method is changed 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from epoll. 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Deletes a file-descriptor from the set of FDs that should be 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // monitored with epoll. 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that this only deals with modifying data relating -directly- 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with the epoll call-- it does not modify any data within the 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server. 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor to-be-removed from the monitoring set 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void DelFD(int fd) const; 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Adds a file-descriptor to the set of FDs that should be 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // monitored with epoll. 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that this only deals with modifying data relating -directly- 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with the epoll call. 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor to-be-added to the monitoring set 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc 595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OR'd together) which will be associated with this 596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // FD initially. 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void AddFD(int fd, int event_mask) const; 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modifies a file-descriptor in the set of FDs that should be 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // monitored with epoll. 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that this only deals with modifying data relating -directly- 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // with the epoll call. 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor to-be-added to the monitoring set 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OR'd together) which will be associated with this 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // FD after this call. 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void ModFD(int fd, int event_mask) const; 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Modified the event mask associated with an FD in the set of 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // data needed by epoll. 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Events are removed before they are added, thus, if ~0 is put 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // in 'remove_event', whatever is put in 'add_event' will be 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the new event mask. 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the file-descriptor specified is not registered in the 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // epoll_server, then nothing happens as a result of this call. 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd - the file descriptor whose event mask is to be modified 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // remove_event - the events which are to be removed from the current 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // event_mask 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // add_event - the events which are to be added to the current event_mask 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void ModifyFD(int fd, int remove_event, int add_event); 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //////////////////////////////////////// 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Waits for events, and calls HandleEvents() for each 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fd, event pair discovered to possibly have an event. 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that a callback (B) may get a spurious event if 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // another callback (A) has closed a file-descriptor N, and 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the callback (B) has a newly opened file-descriptor, which 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // also happens to be N. 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void WaitForEventsAndCallHandleEvents(int64 timeout_in_us, 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct epoll_event events[], 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int events_size); 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // An internal function for implementing the ready list. It adds a fd's 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // CBAndEventMask to the ready list. If the fd is already on the ready 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // list, it is a no-op. 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddToReadyList(CBAndEventMask* cb_and_mask); 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // An internal function for implementing the ready list. It remove a fd's 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // CBAndEventMask from the ready list. If the fd is not on the ready list, 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // it is a no-op. 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RemoveFromReadyList(const CBAndEventMask& cb_and_mask); 658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Calls any pending alarms that should go off and reregisters them if they 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // were recurring. 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void CallAndReregisterAlarmEvents(); 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The file-descriptor created for epolling 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int epoll_fd_; 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The mapping of file-descriptor to CBAndEventMasks 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FDToCBMap cb_map_; 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Custom hash function to be used by hash_set. 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct AlarmCBHash { 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t operator()(AlarmCB*const& p) const { 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return reinterpret_cast<size_t>(p); 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TOOD(sushantj): Having this hash_set is avoidable. We currently have it 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // only so that we can enforce stringent checks that a caller can not register 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the same alarm twice. One option is to have an implementation in which 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // this hash_set is used only in the debug mode. 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef __gnu_cxx::hash_set<AlarmCB*, AlarmCBHash> AlarmCBMap; 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AlarmCBMap all_alarms_; 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TimeToAlarmCBMap alarm_map_; 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The amount of time in microseconds that we'll wait before returning 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // from the WaitForEventsAndExecuteCallbacks() function. 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If this is positive, wait that many microseconds. 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If this is negative, wait forever, or for the first event that occurs 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If this is zero, never wait for an event. 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 timeout_in_us_; 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This is nonzero only after the invocation of epoll_wait_impl within 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndCallHandleEvents and before the function 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks returns. At all other times, this is 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // zero. This enables us to have relatively accurate time returned from the 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ApproximateNowInUs() function. See that function for more details. 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 recorded_now_in_us_; 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This is used to implement CallAndReregisterAlarmEvents. This stores 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // all alarms that were reregistered because OnAlarm() returned a 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // value > 0 and the time at which they should be executed is less that 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the current time. By storing such alarms in this map we ensure 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that while calling CallAndReregisterAlarmEvents we do not call 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OnAlarm on any alarm in this set. This ensures that we do not 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // go in an infinite loop. 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AlarmCBMap alarms_reregistered_and_should_be_skipped_; 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LIST_HEAD(ReadyList, CBAndEventMask) ready_list_; 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LIST_HEAD(TmpList, CBAndEventMask) tmp_list_; 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ready_list_size_; 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(alyssar): make this into something that scales up. 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const int events_size_ = 256; 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct epoll_event events_[256]; 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // These controls the granularity for alarms 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // See function CallAndReregisterAlarmEvents() 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(sushantj): Add test for this. 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 DoRoundingOnNow(int64 now_in_us) const; 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef EPOLL_SERVER_EVENT_TRACING 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct EventRecorder { 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EventRecorder() : num_records_(0), record_threshold_(10000) {} 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~EventRecorder() { 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Clear(); 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // When a number of events equals the record threshold, 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the collected data summary for all FDs will be written 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to LOG(INFO). Note that this does not include the 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // individual events (if you'reinterested in those, you'll 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // have to get at them programmatically). 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // After any such flushing to LOG(INFO) all events will 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // be cleared. 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note that the definition of an 'event' is a bit 'hazy', 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // as it includes the 'Unregistration' event, and perhaps 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // others. 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_record_threshold(int64 new_threshold) { 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott record_threshold_ = new_threshold; 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Clear() { 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < debug_events_.size(); ++i) { 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete debug_events_[i]; 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott debug_events_.clear(); 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unregistered_fds_.clear(); 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_counts_.clear(); 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void MaybeRecordAndClear() { 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++num_records_; 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((num_records_ > record_threshold_) && 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (record_threshold_ > 0)) { 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(INFO) << "\n" << *this; 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_records_ = 0; 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Clear(); 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RecordFDMaskEvent(int fd, int mask, const char* function) { 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function); 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott debug_events_.push_back(fdmo); 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MaybeRecordAndClear(); 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RecordEpollWaitEvent(int timeout_in_ms, 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_events_generated) { 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollWaitOutput* ewo = new EpollWaitOutput(timeout_in_ms, 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_events_generated); 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott debug_events_.push_back(ewo); 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MaybeRecordAndClear(); 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RecordEpollEvent(int fd, int event_mask) { 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Events& events_for_fd = event_counts_[fd]; 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott events_for_fd.AssignFromMask(event_mask); 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MaybeRecordAndClear(); 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend ostream& operator<<(ostream& os, const EventRecorder& er) { 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < er.unregistered_fds_.size(); ++i) { 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "fd: " << er.unregistered_fds_[i] << "\n"; 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << er.unregistered_fds_[i]; 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (EventCountsMap::const_iterator i = er.event_counts_.begin(); 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i != er.event_counts_.end(); 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++i) { 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "fd: " << i->first << "\n"; 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << i->second; 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < er.debug_events_.size(); ++i) { 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << *(er.debug_events_[i]) << "\n"; 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return os; 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void RecordUnregistration(int fd) { 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EventCountsMap::iterator i = event_counts_.find(fd); 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (i != event_counts_.end()) { 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unregistered_fds_.push_back(i->second); 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_counts_.erase(i); 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MaybeRecordAndClear(); 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class DebugOutput { 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) { 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott debug_output.OutputToStream(os); 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return os; 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OutputToStream(ostream* os) const = 0; 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~DebugOutput() {} 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class FDMaskOutput : public DebugOutput { 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FDMaskOutput(int fd, int mask, const char* function) : 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd_(fd), mask_(mask), function_(function) {} 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OutputToStream(ostream* os) const { 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*os) << "func: " << function_ 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << "\tfd: " << fd_; 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (mask_ != 0) { 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*os) << "\tmask: " << EventMaskToString(mask_); 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd_; 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int mask_; 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* function_; 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class EpollWaitOutput : public DebugOutput { 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollWaitOutput(int timeout_in_ms, 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_events_generated) : 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timeout_in_ms_(timeout_in_ms), 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_events_generated_(num_events_generated) {} 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OutputToStream(ostream* os) const { 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*os) << "timeout_in_ms: " << timeout_in_ms_ 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << "\tnum_events_generated: " << num_events_generated_; 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int timeout_in_ms_; 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_events_generated_; 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Events { 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Events() : 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_in(0), 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_pri(0), 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_out(0), 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_rdnorm(0), 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_rdband(0), 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_wrnorm(0), 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_wrband(0), 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_msg(0), 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_err(0), 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_hup(0), 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_oneshot(0), 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott epoll_et(0) {} 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AssignFromMask(int event_mask) { 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLIN) ++epoll_in; 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLPRI) ++epoll_pri; 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLOUT) ++epoll_out; 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLRDNORM) ++epoll_rdnorm; 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLRDBAND) ++epoll_rdband; 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLWRNORM) ++epoll_wrnorm; 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLWRBAND) ++epoll_wrband; 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLMSG) ++epoll_msg; 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLERR) ++epoll_err; 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLHUP) ++epoll_hup; 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLONESHOT) ++epoll_oneshot; 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (event_mask & EPOLLET) ++epoll_et; 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend ostream& operator<<(ostream& os, const Events& ev) { 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_in) { 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLIN: " << ev.epoll_in << "\n"; 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_pri) { 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLPRI: " << ev.epoll_pri << "\n"; 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_out) { 890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLOUT: " << ev.epoll_out << "\n"; 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_rdnorm) { 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLRDNORM: " << ev.epoll_rdnorm << "\n"; 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_rdband) { 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLRDBAND: " << ev.epoll_rdband << "\n"; 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_wrnorm) { 899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLWRNORM: " << ev.epoll_wrnorm << "\n"; 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_wrband) { 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLWRBAND: " << ev.epoll_wrband << "\n"; 903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_msg) { 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLMSG: " << ev.epoll_msg << "\n"; 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_err) { 908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLERR: " << ev.epoll_err << "\n"; 909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_hup) { 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLHUP: " << ev.epoll_hup << "\n"; 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_oneshot) { 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n"; 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ev.epoll_et) { 917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott os << "\t EPOLLET: " << ev.epoll_et << "\n"; 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return os; 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_in; 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_pri; 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_out; 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_rdnorm; 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_rdband; 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_wrnorm; 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_wrband; 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_msg; 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_err; 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_hup; 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_oneshot; 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int epoll_et; 934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<DebugOutput*> debug_events_; 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<Events> unregistered_fds_; 938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef __gnu_cxx::hash_map<int, Events> EventCountsMap; 939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EventCountsMap event_counts_; 940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 num_records_; 941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 record_threshold_; 942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ClearEventRecords() { 945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_recorder_.Clear(); 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void WriteEventRecords(ostream* os) const { 948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*os) << event_recorder_; 949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable EventRecorder event_recorder_; 952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helper functions used in the destructor. 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CleanupFDToCBMap(); 958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CleanupTimeToAlarmCBMap(); 959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The callback registered to the fds below. As the purpose of their 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // registration is to wake the epoll server it just clears the pipe and 962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // returns. 963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<ReadPipeCallback> wake_cb_; 964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // A pipe owned by the epoll server. The server will be registered to listen 966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on read_fd_ and can be woken by Wake() which writes to write_fd_. 967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int read_fd_; 968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int write_fd_; 969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This boolean is checked to see if it is false at the top of the 971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WaitForEventsAndExecuteCallbacks function. If not, then it either returns 972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // without doing work, and logs to ERROR, or aborts the program (in 973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // DEBUG mode). If so, then it sets the bool to true, does work, and 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // sets it back to false when done. This catches unwanted recursion. 975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool in_wait_for_events_and_execute_callbacks_; 976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true when the EpollServer() is being destroyed. 978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool in_shutdown_; 979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(EpollServer); 981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass EpollAlarmCallbackInterface { 984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when an alarm times out. Invalidates an AlarmRegToken. 987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WARNING: If a token was saved to refer to an alarm callback, OnAlarm must 988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // delete it, as the reference is no longer valid. 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns: 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the unix time (in microseconds) at which this alarm should be signaled 991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // again, or 0 if the alarm should be removed. 992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int64 OnAlarm() = 0; 993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the an alarm is registered. Invalidates an AlarmRegToken. 996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Args: 997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // token: the iterator to the the alarm registered in the alarm map. 998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WARNING: this token becomes invalid when the alarm fires, is 999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // unregistered, or OnShutdown is called on that alarm. 1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // eps: the epoll server the alarm is registered with. 1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnRegistration(const EpollServer::AlarmRegToken& token, 1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollServer* eps) = 0; 1003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 1005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the an alarm is unregistered. 1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // WARNING: It is not valid to unregister a callback and then use the token 1007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that was saved to refer to the callback. 1008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnUnregistration() = 0; 1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Summary: 1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called when the epoll server is shutting down. 1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Invalidates the AlarmRegToken that was given when this alarm was 1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // registered. 1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnShutdown(EpollServer* eps) = 0; 1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~EpollAlarmCallbackInterface() {} 1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollAlarmCallbackInterface() {} 1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A simple alarm which unregisters itself on destruction. 1023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 1024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// PLEASE NOTE: 1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Any classes overriding these functions must either call the implementation 1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of the parent class, or is must otherwise make sure that the 'registered_' 1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// boolean and the token, 'token_', are updated appropriately. 1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass EpollAlarm : public EpollAlarmCallbackInterface { 1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollAlarm(); 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~EpollAlarm(); 1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Marks the alarm as unregistered and returns 0. The return value may be 1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // safely ignored by subclasses. 1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int64 OnAlarm(); 1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Marks the alarm as registered, and stores the token. 1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnRegistration(const EpollServer::AlarmRegToken& token, 1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollServer* eps); 1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Marks the alarm as unregistered. 1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnUnregistration(); 1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Marks the alarm as unregistered. 1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnShutdown(EpollServer* eps); 1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If the alarm was registered, unregister it. 1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void UnregisterIfRegistered(); 1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool registered() const { return registered_; } 1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const EpollServer* eps() const { return eps_; } 1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollServer::AlarmRegToken token_; 1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EpollServer* eps_; 1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool registered_; 1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_TOOLS_FLIP_SERVER_EPOLL_SERVER_H_ 1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1065