/sparrowhawk/foundation/ESFEpollMultiplexer.h
C Header | 182 lines | 66 code | 28 blank | 88 comment | 0 complexity | 37b96575cd27feb59a8e4ee1b9f389d7 MD5 | raw file
1/** @file ESFEpollMultiplexer.h 2 * @brief A linux epoll-based implementation of ESFSocketMultiplexer 3 * 4 * Copyright (c) 2009 Yahoo! Inc. 5 * The copyrights embodied in the content of this file are licensed by Yahoo! Inc. 6 * under the BSD (revised) open source license. 7 * 8 * Derived from code that is Copyright (c) 2009 Joshua Blatt and offered under both 9 * BSD and Apache 2.0 licenses (http://sourceforge.net/projects/sparrowhawk/). 10 * 11 * $Author: blattj $ 12 * $Date: 2009/05/25 21:51:08 $ 13 * $Name: $ 14 * $Revision: 1.3 $ 15 */ 16 17#ifndef ESF_EPOLL_MULTIPLEXER_H 18#define ESF_EPOLL_MULTIPLEXER_H 19 20#ifndef ESF_SOCKET_MULTIPLEXER_H 21#include <ESFSocketMultiplexer.h> 22#endif 23 24#ifndef ESF_SHARED_COUNTER_H 25#include <ESFSharedCounter.h> 26#endif 27 28#ifndef ESF_ALLOCATOR_H 29#include <ESFAllocator.h> 30#endif 31 32#ifndef ESF_EMBEDDED_LIST_H 33#include <ESFEmbeddedList.h> 34#endif 35 36#ifndef ESF_MUTEX_H 37#include <ESFMutex.h> 38#endif 39 40#ifndef ESF_SHARED_COUNTER_H 41#include <ESFSharedCounter.h> 42#endif 43 44#ifdef HAVE_TIME_H 45#include <time.h> 46#endif 47 48#ifdef HAVE_SYS_EPOLL_H 49#include <sys/epoll.h> 50#endif 51 52/** A linux epoll-based implementation of ESFSocketMultiplexer. 53 * 54 * @ingroup thread 55 */ 56class ESFEpollMultiplexer: public ESFSocketMultiplexer { 57public: 58 59 /** Constructor. 60 * 61 * @param name The name of the multiplexer to be used in log messages. Caller is responsible 62 * for the strings memory - use a string literal if possible. 63 * @param maxSockets The maximum number of sockets the multiplexer will 64 * handle. When this limit is hit, the multiplexer will stop accepting 65 * new connections from any listening sockets and reject any application 66 * requests to add new sockets. 67 * @param logger An optional logger. Pass NULL to not log anything. 68 * @param allocator Internal storage will be allocated using this allocator. 69 */ 70 ESFEpollMultiplexer(const char *name, int maxSockets, ESFLogger *logger, ESFAllocator *allocator); 71 72 /** Destructor. 73 */ 74 virtual ~ESFEpollMultiplexer(); 75 76 /** Return an optional handler that can destroy the multiplexer. 77 * 78 * @return A handler to destroy the element or NULL if the element should not be destroyed. 79 */ 80 virtual ESFCleanupHandler *getCleanupHandler(); 81 82 /** Get the name of the multiplexer. This name can be used in logging messages, etc. 83 * 84 * @return The multiplexer's name 85 */ 86 virtual const char *getName() const; 87 88 /** Initialize the multiplexer 89 * 90 * @return ESF_SUCCESS if successful, another error code otherwise 91 */ 92 virtual ESFError initialize(); 93 94 /** Destroy the multiplexer 95 * 96 */ 97 virtual void destroy(); 98 99 /** Add a new multiplexed socket to the socket multiplexer 100 * 101 * @param multiplexedSocket The multiplexed socket 102 * @return ESF_SUCCESS if successful, ESF_OVERFLOW if the maxSockets limit has 103 * been reached, another error code otherwise. 104 */ 105 virtual ESFError addMultiplexedSocket(ESFMultiplexedSocket *multiplexedSocket); 106 107 /** Run the multiplexer's event loop until shutdown. 108 * 109 * @param isRunning This object will return true as long as the controlling thread 110 * isRunning, false when the controlling thread wants to shutdown. 111 * @return If true, caller should destroy the command with the CleanupHandler. 112 */ 113 virtual bool run(ESFFlag *isRunning); 114 115 /** Get the number of sockets this multiplexer is currently handling. 116 * 117 * @return the number of sockets this multiplexer is currently handling. 118 */ 119 virtual int getCurrentSockets(); 120 121 /** Get the maximum number of sockets this multiplexer can handle. 122 * 123 * @return the maximum number of sockets this multiplexer can handle. 124 */ 125 virtual int getMaximumSockets(); 126 127 /** Placement new. 128 * 129 * @param size The size of the object. 130 * @param allocator The source of the object's memory. 131 * @return Memory for the new object or NULL if the memory allocation failed. 132 */ 133 inline void *operator new(size_t size, ESFAllocator *allocator) { 134 return allocator->allocate(size); 135 } 136 137private: 138 139 // Disabled 140 ESFEpollMultiplexer(const ESFEpollMultiplexer &); 141 ESFEpollMultiplexer &operator=(const ESFEpollMultiplexer &); 142 143 /** Keep socket in epoll and socket list, but possibly change the readiness 144 * events of interest. This does not modify the _currentSocketCount. 145 * 146 * @param multiplexedSocket The multiplexedSocket 147 */ 148 ESFError updateMultiplexedSocket(ESFFlag *isRunning, ESFMultiplexedSocket *multiplexedSocket); 149 150 /** Remove a multiplexed socket form the socket multiplexer 151 * 152 * @param multiplexedSocket The multiplexed socket to remove 153 */ 154 ESFError removeMultiplexedSocket(ESFFlag *isRunning, ESFMultiplexedSocket *multiplexedSocket, bool removeFromList = 155 true); 156 157 /** Periodically check for any idle sockets and delete them. 158 * 159 * @param isRunning This object will return true as long as the controlling thread 160 * isRunning, false when the controlling thread wants to shutdown. 161 */ 162 ESFError checkIdleSockets(ESFFlag *isRunning); 163 164 int _epollDescriptor; 165 int _maxSockets; 166#ifdef HAVE_TIME_T 167 time_t _lastIdleCheckSec; 168#else 169#error "time_t or equilvalent is required" 170#endif 171#ifdef HAVE_STRUCT_EPOLL_EVENT 172 struct epoll_event *_events; 173#else 174#error "struct epoll_event is required" 175#endif 176 ESFAllocator *_allocator; 177 ESFSharedCounter _currentSocketCount; 178 ESFEmbeddedList _currentSocketList; 179 ESFMutex _lock; 180}; 181 182#endif /* ! ESF_EPOLL_MULTIPLEXER_H */