PageRenderTime 12ms CodeModel.GetById 8ms app.highlight 3ms RepoModel.GetById 0ms app.codeStats 0ms

/sparrowhawk/foundation/ESFEpollMultiplexer.h

http://github.com/jtblatt/duderino
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 */