14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_ 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/queue.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <set> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #define EPOLL_SERVER_EVENT_TRACING 1 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defining EPOLL_SERVER_EVENT_TRACING 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// causes code to exist which didn't before. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This code tracks each event generated by the epollserver, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as well as providing a per-fd-registered summary of 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// events. Note that enabling this code vastly slows 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// down operations, and uses substantially more 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// memory. For these reasons, it should only be enabled when doing 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// developer debugging at his/her workstation. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A structure called 'EventRecorder' will exist when 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the macro is defined. See the EventRecorder class interface 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// within the EpollServer class for more details. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef EPOLL_SERVER_EVENT_TRACING 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/epoll.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EpollServer; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EpollAlarmCallbackInterface; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReadPipeCallback; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct EpollEvent { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollEvent(int events, bool is_epoll_wait) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : in_events(events), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_ready_mask(0) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int in_events; // incoming events 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int out_ready_mask; // the new event mask for ready list (0 means don't 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get on the ready list). This field is always 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialized to 0 when the event is passed to 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnEvent. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callbacks which go into EpollServers are expected to derive from this class. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EpollCallbackInterface { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the callback is registered into a EpollServer. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // eps - the poll server into which this callback was registered 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor which was registered 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which was registered (and will initially be used 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the epoll() calls) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) = 0; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the event_mask is modified (for a file-descriptor) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor which was registered 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which was is now curren (and will be used 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in subsequent epoll() calls) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnModification(int fd, int event_mask) = 0; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called whenever an event occurs on the file-descriptor. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is where the bulk of processing is expected to occur. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor which was registered 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event - a struct that contains the event mask (composed of EPOLLIN, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EPOLLOUT, etc), a flag that indicates whether this is a true 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_wait event vs one from the ready list, and an output 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter for OnEvent to inform the EpollServer whether to put 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this fd on the ready list. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnEvent(int fd, EpollEvent* event) = 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the file-descriptor is unregistered from the poll-server. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor which was registered, and of this call, is now 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unregistered. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // replaced - If true, this callback is being replaced by another, otherwise 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is simply being removed. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnUnregistration(int fd, bool replaced) = 0; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the epoll server is shutting down. This is different from 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnUnregistration because the subclass may want to clean up memory. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is called in leiu of OnUnregistration. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor which was registered. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnShutdown(EpollServer* eps, int fd) = 0; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~EpollCallbackInterface() {} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollCallbackInterface() {} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EpollServer { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef EpollAlarmCallbackInterface AlarmCB; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef EpollCallbackInterface CB; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::multimap<int64, AlarmCB*> TimeToAlarmCBMap; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef TimeToAlarmCBMap::iterator AlarmRegToken; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructor: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // By default, we don't wait any amount of time for events, and 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we suggest to the epoll-system that we're going to use on-the-order 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of 1024 FDs. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destructor 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~EpollServer(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register a callback to be called whenever an event contained 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the set of events included in event_mask occurs on the 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file-descriptor 'fd' 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that only one callback is allowed to be registered for 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any specific file-decriptor. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a callback is registered for a file-descriptor which has already 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // been registered, then the previous callback is unregistered with 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the 'replaced' flag set to true. I.e. the previous callback's 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnUnregistration() function is called like so: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnUnregistration(fd, true); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The epoll server does NOT take on ownership of the callback: the callback 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // creator is responsible for managing that memory. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - a valid file-descriptor 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cb - an instance of a subclass of EpollCallbackInterface 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the events for which the callback would like to be 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RegisterFD(int fd, CB* cb, int event_mask); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shortcut for RegisterFD which sets things up such that the 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback is called when 'fd' is available for writing. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - a valid file-descriptor 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cb - an instance of a subclass of EpollCallbackInterface 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RegisterFDForWrite(int fd, CB* cb); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shortcut for RegisterFD which sets things up such that the 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback is called when 'fd' is available for reading or writing. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - a valid file-descriptor 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cb - an instance of a subclass of EpollCallbackInterface 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RegisterFDForReadWrite(int fd, CB* cb); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shortcut for RegisterFD which sets things up such that the 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback is called when 'fd' is available for reading. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - a valid file-descriptor 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cb - an instance of a subclass of EpollCallbackInterface 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RegisterFDForRead(int fd, CB* cb); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes the FD and the associated callback from the pollserver. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the callback is registered with other FDs, they will continue 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be processed using the callback without modification. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file-descriptor which should no-longer be monitored. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void UnregisterFD(int fd); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modifies the event mask for the file-descriptor, replacing 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the old event_mask with the new one specified here. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the fd whose event mask should be modified. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - the new event mask. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ModifyCallback(int fd, int event_mask); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modifies the event mask for the file-descriptor such that we 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no longer request events when 'fd' is readable. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the fd whose event mask should be modified. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StopRead(int fd); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modifies the event mask for the file-descriptor such that we 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request events when 'fd' is readable. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the fd whose event mask should be modified. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StartRead(int fd); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modifies the event mask for the file-descriptor such that we 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no longer request events when 'fd' is writable. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the fd whose event mask should be modified. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StopWrite(int fd); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modifies the event mask for the file-descriptor such that we 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request events when 'fd' is writable. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the fd whose event mask should be modified. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StartWrite(int fd); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Looks up the callback associated with the file-desriptor 'fd'. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a callback is associated with this file-descriptor, then 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's OnEvent() method is called with the file-descriptor 'fd', 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and event_mask 'event_mask' 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If no callback is registered for this file-descriptor, nothing 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will happen as a result of this call. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function is used internally by the EpollServer, but is 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // available publically so that events might be 'faked'. Calling 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this function with an fd and event_mask is equivalent (as far 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the callback is concerned) to having a real event generated 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by epoll (except, of course, that read(), etc won't necessarily 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be able to read anything) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file-descriptor on which an event has occured. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - a bitmask representing the events which have occured 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on/for this fd. This bitmask is composed of 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // POLLIN, POLLOUT, etc. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleEvent(int fd, int event_mask); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call this when you want the pollserver to 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wait for events and execute the callbacks associated with 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the file-descriptors on which those events have occured. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Depending on the value of timeout_in_us_, this may or may 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not return immediately. Please reference the set_timeout() 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function for the specific behaviour. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WaitForEventsAndExecuteCallbacks(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When an fd is registered to use edge trigger notification, the ready 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list can be used to simulate level trigger semantics. Edge trigger 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registration doesn't send an initial event, and only rising edge (going 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from blocked to unblocked) events are sent. A callback can put itself on 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the ready list by calling SetFDReady() after calling RegisterFD(). The 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnEvent method of all callbacks associated with the fds on the ready 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list will be called immediately after processing the events returned by 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_wait(). The fd is removed from the ready list before the 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback's OnEvent() method is invoked. To stay on the ready list, the 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnEvent() (or some function in that call chain) must call SetFDReady 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // again. When a fd is unregistered using UnregisterFD(), the fd is 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // automatically removed from the ready list. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the callback for a edge triggered fd hits the falling edge (about 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to block, either because of it got an EAGAIN, or had a short read/write 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operation), it should remove itself from the ready list using 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetFDNotReady() (since OnEvent cannot distinguish between invocation 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the ready list vs from a normal epoll event). All four ready list 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // methods are safe to be called within the context of the callbacks. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the ready list invokes EpollCallbackInterface::OnEvent, only fds 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that are registered with the EpollServer will be put on the ready list. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetFDReady() and SetFDNotReady() will do nothing if the EpollServer 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // doesn't know about the fd passed in. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the ready list cannot reliably determine proper set of events 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which should be sent to the callback, SetFDReady() requests the caller 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to provide the ready list with the event mask, which will be used later 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when OnEvent() is invoked by the ready list. Hence, the event_mask 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // passedto SetFDReady() does not affect the actual epoll registration of 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the fd with the kernel. If a fd is already put on the ready list, and 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetFDReady() is called again for that fd with a different event_mask, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event_mask will be updated. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetFDReady(int fd, int events_to_fake); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetFDNotReady(int fd); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // debugging tools and for writing unit tests. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ISFDReady() returns whether a fd is in the ready list. 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReadyListSize() returns the number of fds on the ready list. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // VerifyReadyList() checks the consistency of internal data structure. It 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will CHECK if it finds an error. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsFDReady(int fd) const; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t ReadyListSize() const { return ready_list_size_; } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyReadyList() const; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Registers an alarm 'ac' to go off at time 'timeout_time_in_us'. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the callback returns a positive number from its OnAlarm() function, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then the callback will be re-registered at that time, else the alarm 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // owner is responsible for freeing up memory. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Important: A give AlarmCB* can not be registered again if it is already 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registered. If a user wants to register a callback again it should first 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unregister the previous callback before calling RegisterAlarm again. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout_time_in_us - the absolute time at which the alarm should go off 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ac - the alarm which will be called. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RegisterAlarm(int64 timeout_time_in_us, AlarmCB* ac); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() + 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delta_in_us). While this is somewhat less accurate (see the description 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for ApproximateNowInUs() to see how 'approximate'), the error is never 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // worse than the amount of time it takes to process all events in one 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEvents. As with 'RegisterAlarm()', if the callback returns a 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // positive number from its OnAlarm() function, then the callback will be 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-registered at that time, else the alarm owner is responsible for 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // freeing up memory. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this function is purely a convienence. The 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same thing may be accomplished by using RegisterAlarm with 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ApproximateNowInUs() directly. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Important: A give AlarmCB* can not be registered again if it is already 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registered. If a user wants to register a callback again it should first 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unregister the previous callback before calling RegisterAlarm again. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which point the alarm should go off. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ac - the alarm which will be called. 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RegisterAlarmApproximateDelta(int64 delta_in_us, AlarmCB* ac) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unregister the alarm referred to by iterator_token; Callers should 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be warned that a token may have become already invalid when OnAlarm() 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is called, was unregistered, or OnShutdown was called on that alarm. 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // iterator_token - iterator to the alarm callback to unregister. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void UnregisterAlarm( 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EpollServer::AlarmRegToken& iterator_token); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns the number of file-descriptors registered in this EpollServer. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns: 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of FDs registered (discounting the internal pipe used for Wake) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int NumFDsRegistered() const; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force the epoll server to wake up (by writing to an internal pipe). 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Wake(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrapper around WallTimer's NowInUsec. We do this so that we can test 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EpollServer without using the system clock (and can avoid the flakiness 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that would ensue) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns: 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the current time as number of microseconds since the Unix epoch. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int64 NowInUsec() const; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since calling NowInUsec() many thousands of times per 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks function call is, to say the least, 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inefficient, we allow users to use an approximate time instead. The 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time returned from this function is as accurate as NowInUsec() when 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callstack. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this function returns the time at which the 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks function started to process events or 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alarms. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Essentially, this function makes available a fast and mostly accurate 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mechanism for getting the time for any function handling an event or 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alarm. When functions which are not handling callbacks or alarms call 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this function, they get the slow and "absolutely" accurate time. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Users should be encouraged to use this function. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns: 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the "approximate" current time as number of microseconds since the Unix 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoch. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int64 ApproximateNowInUsec() const; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static std::string EventMaskToString(int event_mask); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Logs the state of the epoll server with LOG(ERROR). 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LogStateOnCrash(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the timeout to the value specified. 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the timeout is set to a negative number, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks() will only return when an event has 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occured 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the timeout is set to zero, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks() will return immediately 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the timeout is set to a positive number, 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks() will return when an event has 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occured, or when timeout_in_us microseconds has elapsed, whichever 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is first. 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout_in_us - value specified depending on behaviour desired. 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above. 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_timeout_in_us(int64 timeout_in_us) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_in_us_ = timeout_in_us; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accessor for the current value of timeout_in_us. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_in_us() const { return timeout_in_us_; } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true when the EpollServer() is being destroyed. 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool in_shutdown() const { return in_shutdown_; } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ContainsAlarm(EpollAlarmCallbackInterface* alarm) const { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return all_alarms_.find(alarm) != all_alarms_.end(); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A function for implementing the ready list. It invokes OnEvent for each 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the fd in the ready list, and takes care of adding them back to the 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ready list if the callback requests it (by checking that out_ready_mask 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is non-zero). 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CallReadyListCallbacks(); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetFlags(int fd); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline int SetFlags(int fd, int flags) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fcntl(fd, F_SETFL, flags | O_NONBLOCK); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetNonblocking(int fd); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This exists here so that we can override this function in unittests 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in order to make effective mock EpollServer objects. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int epoll_wait_impl(int epfd, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct epoll_event* events, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_events, 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_in_ms); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this struct is used internally, and is never used by anything external 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to this class. Some of its members are declared mutable to get around the 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // restriction imposed by hash_set. Since hash_set knows nothing about the 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // objects it stores, it has to assume that every bit of the object is used 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the hash function and equal_to comparison. Thus hash_set::iterator is a 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // const iterator. In this case, the only thing that must stay constant is 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd. Everything else are just along for the ride and changing them doesn't 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compromise the hash_set integrity. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct CBAndEventMask { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBAndEventMask() 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : cb(NULL), 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd(-1), 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_mask(0), 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_asserted(0), 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_to_fake(0), 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_use(false) { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.le_next = NULL; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.le_prev = NULL; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBAndEventMask(EpollCallbackInterface* cb, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int event_mask, 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : cb(cb), fd(fd), event_mask(event_mask), events_asserted(0), 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_to_fake(0), in_use(false) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.le_next = NULL; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.le_prev = NULL; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Required operator for hash_set. Normally operator== should be a free 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // standing function. However, since CBAndEventMask is a protected type and 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it will never be a base class, it makes no difference. 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const CBAndEventMask& cb_and_mask) const { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fd == cb_and_mask.fd; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A callback. If the fd is unregistered inside the callchain of OnEvent, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the cb will be set to NULL. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable EpollCallbackInterface* cb; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable LIST_ENTRY(CBAndEventMask) entry; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file descriptor registered with the epoll server. 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the current event_mask registered for this callback. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable int event_mask; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event_mask that was returned by epoll 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable int events_asserted; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event_mask for the ready list to use to call OnEvent. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable int events_to_fake; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // toggle around calls to OnEvent to tell UnregisterFD to not erase the 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // iterator because HandleEvent is using it. 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable bool in_use; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Custom hash function to be used by hash_set. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct CBAndEventMaskHash { 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t operator()(const CBAndEventMask& cb_and_eventmask) const { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<size_t>(cb_and_eventmask.fd); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef base::hash_set<CBAndEventMask, CBAndEventMaskHash> FDToCBMap; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the following four functions are OS-specific, and are likely 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be changed in a subclass if the poll/select method is changed 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from epoll. 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes a file-descriptor from the set of FDs that should be 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // monitored with epoll. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this only deals with modifying data relating -directly- 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the epoll call-- it does not modify any data within the 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server. 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor to-be-removed from the monitoring set 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DelFD(int fd) const; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a file-descriptor to the set of FDs that should be 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // monitored with epoll. 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this only deals with modifying data relating -directly- 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the epoll call. 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor to-be-added to the monitoring set 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OR'd together) which will be associated with this 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FD initially. 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddFD(int fd, int event_mask) const; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modifies a file-descriptor in the set of FDs that should be 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // monitored with epoll. 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this only deals with modifying data relating -directly- 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the epoll call. 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor to-be-added to the monitoring set 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OR'd together) which will be associated with this 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FD after this call. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ModFD(int fd, int event_mask) const; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Modified the event mask associated with an FD in the set of 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data needed by epoll. 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Events are removed before they are added, thus, if ~0 is put 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in 'remove_event', whatever is put in 'add_event' will be 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the new event mask. 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the file-descriptor specified is not registered in the 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // epoll_server, then nothing happens as a result of this call. 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd - the file descriptor whose event mask is to be modified 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remove_event - the events which are to be removed from the current 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event_mask 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add_event - the events which are to be added to the current event_mask 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ModifyFD(int fd, int remove_event, int add_event); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////////////////////////////////////// 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Waits for events, and calls HandleEvents() for each 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fd, event pair discovered to possibly have an event. 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that a callback (B) may get a spurious event if 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // another callback (A) has closed a file-descriptor N, and 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback (B) has a newly opened file-descriptor, which 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also happens to be N. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WaitForEventsAndCallHandleEvents(int64 timeout_in_us, 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct epoll_event events[], 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int events_size); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An internal function for implementing the ready list. It adds a fd's 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBAndEventMask to the ready list. If the fd is already on the ready 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // list, it is a no-op. 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddToReadyList(CBAndEventMask* cb_and_mask); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An internal function for implementing the ready list. It remove a fd's 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBAndEventMask from the ready list. If the fd is not on the ready list, 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is a no-op. 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveFromReadyList(const CBAndEventMask& cb_and_mask); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calls any pending alarms that should go off and reregisters them if they 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // were recurring. 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CallAndReregisterAlarmEvents(); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The file-descriptor created for epolling 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int epoll_fd_; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The mapping of file-descriptor to CBAndEventMasks 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FDToCBMap cb_map_; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Custom hash function to be used by hash_set. 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct AlarmCBHash { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t operator()(AlarmCB*const& p) const { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<size_t>(p); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TOOD(sushantj): Having this hash_set is avoidable. We currently have it 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only so that we can enforce stringent checks that a caller can not register 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same alarm twice. One option is to have an implementation in which 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this hash_set is used only in the debug mode. 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef base::hash_set<AlarmCB*, AlarmCBHash> AlarmCBMap; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlarmCBMap all_alarms_; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeToAlarmCBMap alarm_map_; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The amount of time in microseconds that we'll wait before returning 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the WaitForEventsAndExecuteCallbacks() function. 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is positive, wait that many microseconds. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is negative, wait forever, or for the first event that occurs 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is zero, never wait for an event. 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 timeout_in_us_; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is nonzero only after the invocation of epoll_wait_impl within 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndCallHandleEvents and before the function 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks returns. At all other times, this is 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // zero. This enables us to have relatively accurate time returned from the 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ApproximateNowInUs() function. See that function for more details. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 recorded_now_in_us_; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is used to implement CallAndReregisterAlarmEvents. This stores 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all alarms that were reregistered because OnAlarm() returned a 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value > 0 and the time at which they should be executed is less that 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the current time. By storing such alarms in this map we ensure 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that while calling CallAndReregisterAlarmEvents we do not call 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnAlarm on any alarm in this set. This ensures that we do not 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // go in an infinite loop. 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlarmCBMap alarms_reregistered_and_should_be_skipped_; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LIST_HEAD(ReadyList, CBAndEventMask) ready_list_; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LIST_HEAD(TmpList, CBAndEventMask) tmp_list_; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ready_list_size_; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(alyssar): make this into something that scales up. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int events_size_ = 256; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct epoll_event events_[256]; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef EPOLL_SERVER_EVENT_TRACING 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct EventRecorder { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventRecorder() : num_records_(0), record_threshold_(10000) {} 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~EventRecorder() { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When a number of events equals the record threshold, 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the collected data summary for all FDs will be written 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to LOG(INFO). Note that this does not include the 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // individual events (if you'reinterested in those, you'll 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have to get at them programmatically). 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After any such flushing to LOG(INFO) all events will 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be cleared. 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the definition of an 'event' is a bit 'hazy', 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as it includes the 'Unregistration' event, and perhaps 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // others. 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_record_threshold(int64 new_threshold) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) record_threshold_ = new_threshold; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Clear() { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < debug_events_.size(); ++i) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete debug_events_[i]; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_events_.clear(); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unregistered_fds_.clear(); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_counts_.clear(); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MaybeRecordAndClear() { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_records_; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((num_records_ > record_threshold_) && 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (record_threshold_ > 0)) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "\n" << *this; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_records_ = 0; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordFDMaskEvent(int fd, int mask, const char* function) { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_events_.push_back(fdmo); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeRecordAndClear(); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordEpollWaitEvent(int timeout_in_ms, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_events_generated) { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollWaitOutput* ewo = new EpollWaitOutput(timeout_in_ms, 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_events_generated); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_events_.push_back(ewo); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeRecordAndClear(); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordEpollEvent(int fd, int event_mask) { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Events& events_for_fd = event_counts_[fd]; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_for_fd.AssignFromMask(event_mask); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeRecordAndClear(); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend ostream& operator<<(ostream& os, const EventRecorder& er) { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < er.unregistered_fds_.size(); ++i) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "fd: " << er.unregistered_fds_[i] << "\n"; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << er.unregistered_fds_[i]; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (EventCountsMap::const_iterator i = er.event_counts_.begin(); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != er.event_counts_.end(); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "fd: " << i->first << "\n"; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << i->second; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < er.debug_events_.size(); ++i) { 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << *(er.debug_events_[i]) << "\n"; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return os; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordUnregistration(int fd) { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventCountsMap::iterator i = event_counts_.find(fd); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != event_counts_.end()) { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unregistered_fds_.push_back(i->second); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_counts_.erase(i); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeRecordAndClear(); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DebugOutput { 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_output.OutputToStream(os); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return os; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OutputToStream(ostream* os) const = 0; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DebugOutput() {} 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class FDMaskOutput : public DebugOutput { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FDMaskOutput(int fd, int mask, const char* function) : 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_(fd), mask_(mask), function_(function) {} 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OutputToStream(ostream* os) const { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*os) << "func: " << function_ 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\tfd: " << fd_; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mask_ != 0) { 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*os) << "\tmask: " << EventMaskToString(mask_); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd_; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mask_; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* function_; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class EpollWaitOutput : public DebugOutput { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollWaitOutput(int timeout_in_ms, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_events_generated) : 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_in_ms_(timeout_in_ms), 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_events_generated_(num_events_generated) {} 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OutputToStream(ostream* os) const { 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*os) << "timeout_in_ms: " << timeout_in_ms_ 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\tnum_events_generated: " << num_events_generated_; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_in_ms_; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_events_generated_; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Events { 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Events() : 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_in(0), 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_pri(0), 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_out(0), 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_rdnorm(0), 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_rdband(0), 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_wrnorm(0), 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_wrband(0), 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_msg(0), 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_err(0), 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_hup(0), 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_oneshot(0), 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_et(0) {} 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AssignFromMask(int event_mask) { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLIN) ++epoll_in; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLPRI) ++epoll_pri; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLOUT) ++epoll_out; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLRDNORM) ++epoll_rdnorm; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLRDBAND) ++epoll_rdband; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLWRNORM) ++epoll_wrnorm; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLWRBAND) ++epoll_wrband; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLMSG) ++epoll_msg; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLERR) ++epoll_err; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLHUP) ++epoll_hup; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLONESHOT) ++epoll_oneshot; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_mask & EPOLLET) ++epoll_et; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend ostream& operator<<(ostream& os, const Events& ev) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_in) { 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLIN: " << ev.epoll_in << "\n"; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_pri) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLPRI: " << ev.epoll_pri << "\n"; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_out) { 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLOUT: " << ev.epoll_out << "\n"; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_rdnorm) { 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLRDNORM: " << ev.epoll_rdnorm << "\n"; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_rdband) { 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLRDBAND: " << ev.epoll_rdband << "\n"; 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_wrnorm) { 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLWRNORM: " << ev.epoll_wrnorm << "\n"; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_wrband) { 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLWRBAND: " << ev.epoll_wrband << "\n"; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_msg) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLMSG: " << ev.epoll_msg << "\n"; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_err) { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLERR: " << ev.epoll_err << "\n"; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_hup) { 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLHUP: " << ev.epoll_hup << "\n"; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_oneshot) { 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n"; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev.epoll_et) { 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os << "\t EPOLLET: " << ev.epoll_et << "\n"; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return os; 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_in; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_pri; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_out; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_rdnorm; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_rdband; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_wrnorm; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_wrband; 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_msg; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_err; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_hup; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_oneshot; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int epoll_et; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DebugOutput*> debug_events_; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Events> unregistered_fds_; 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef base::hash_map<int, Events> EventCountsMap; 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventCountsMap event_counts_; 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_records_; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 record_threshold_; 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearEventRecords() { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_recorder_.Clear(); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteEventRecords(ostream* os) const { 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*os) << event_recorder_; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable EventRecorder event_recorder_; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper functions used in the destructor. 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CleanupFDToCBMap(); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CleanupTimeToAlarmCBMap(); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback registered to the fds below. As the purpose of their 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registration is to wake the epoll server it just clears the pipe and 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns. 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ReadPipeCallback> wake_cb_; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A pipe owned by the epoll server. The server will be registered to listen 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on read_fd_ and can be woken by Wake() which writes to write_fd_. 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read_fd_; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_fd_; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This boolean is checked to see if it is false at the top of the 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WaitForEventsAndExecuteCallbacks function. If not, then it either returns 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without doing work, and logs to ERROR, or aborts the program (in 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DEBUG mode). If so, then it sets the bool to true, does work, and 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sets it back to false when done. This catches unwanted recursion. 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool in_wait_for_events_and_execute_callbacks_; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true when the EpollServer() is being destroyed. 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool in_shutdown_; 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EpollServer); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EpollAlarmCallbackInterface { 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when an alarm times out. Invalidates an AlarmRegToken. 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: If a token was saved to refer to an alarm callback, OnAlarm must 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // delete it, as the reference is no longer valid. 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns: 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the unix time (in microseconds) at which this alarm should be signaled 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // again, or 0 if the alarm should be removed. 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int64 OnAlarm() = 0; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the an alarm is registered. Invalidates an AlarmRegToken. 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Args: 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // token: the iterator to the the alarm registered in the alarm map. 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: this token becomes invalid when the alarm fires, is 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unregistered, or OnShutdown is called on that alarm. 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // eps: the epoll server the alarm is registered with. 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnRegistration(const EpollServer::AlarmRegToken& token, 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer* eps) = 0; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the an alarm is unregistered. 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: It is not valid to unregister a callback and then use the token 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that was saved to refer to the callback. 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnUnregistration() = 0; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Summary: 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the epoll server is shutting down. 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invalidates the AlarmRegToken that was given when this alarm was 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registered. 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnShutdown(EpollServer* eps) = 0; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~EpollAlarmCallbackInterface() {} 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollAlarmCallbackInterface() {} 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple alarm which unregisters itself on destruction. 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PLEASE NOTE: 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Any classes overriding these functions must either call the implementation 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the parent class, or is must otherwise make sure that the 'registered_' 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// boolean and the token, 'token_', are updated appropriately. 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EpollAlarm : public EpollAlarmCallbackInterface { 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollAlarm(); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~EpollAlarm(); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Marks the alarm as unregistered and returns 0. The return value may be 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // safely ignored by subclasses. 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int64 OnAlarm() OVERRIDE; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Marks the alarm as registered, and stores the token. 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnRegistration(const EpollServer::AlarmRegToken& token, 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer* eps) OVERRIDE; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Marks the alarm as unregistered. 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnUnregistration() OVERRIDE; 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Marks the alarm as unregistered. 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnShutdown(EpollServer* eps) OVERRIDE; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the alarm was registered, unregister it. 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnregisterIfRegistered(); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool registered() const { return registered_; } 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EpollServer* eps() const { return eps_; } 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer::AlarmRegToken token_; 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer* eps_; 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool registered_; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif // NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_ 1054