/usr/include/assa-3.5/assa/Reactor.h is in libassa-3.5-5-dev 3.5.1-6build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | // -*- c++ -*-
//------------------------------------------------------------------------------
// Reactor.h
//------------------------------------------------------------------------------
// Copyright (C) 1997-2002,2005 Vladislav Grinchenko
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
// Created: 05/25/1999
//------------------------------------------------------------------------------
#ifndef REACTOR_H
#define REACTOR_H
#include <sys/time.h> // select(2)
#include <map>
#if !defined(WIN32)
# include <sys/resource.h> // getrlimit(2)
#endif
#include "assa/EventHandler.h"
#include "assa/Singleton.h"
#include "assa/MaskSet.h"
#include "assa/TimerQueue.h"
#include "assa/TimerCountdown.h"
namespace ASSA {
/** @file Reactor.h
An implementation of Reactor pattern.
This class takes after Reactor pattern described in "An Object Behavioral
Pattern for Demultiplexing and Dispatching Handles for Synchronous Events"
by D.C. Schmidt.
Design of it is highly influenced by ACE's own implementation of Reactor
class as well as by InterViews V 3.1 from Stanford University.
Reactor reads data from a file descriptor, writes data to a file
descriptor, handles an I/O exception on a file descriptor, or handles
a timer's expiration. Once the user has requested the Reactor to attach
EventHandler to a file descriptor or a timer, Reactor will
automatically notify the EventHandler when the file descriptor's
I/O condition changes to the timer expires.
Most of the time, however, event processing is shared with some other
event processor, such as X event loop routine of Gtk+ or another communication
framework such as CORBA. In this case, timed event loop is used.
This can be achieved by calling Reactor::waitForEvents (TimeVal* tv_).
*/
class Reactor
{
public:
/// Constructor.
Reactor ();
/// Destructor.
~Reactor();
/** Register Timer Event handler with Reactor. Reactor will dispatch
appropriate callback when event of EventType is received.
@param eh_ Pointer to the EventHandler
@param tv_ Timeout value
@param name_ Name of the timer
@return Timer ID that can be used to cancel timer and find out its
name.
*/
TimerId registerTimerHandler (EventHandler* eh_,
const TimeVal& tv_,
const std::string& name_ = "<unknown>");
/** Register I/O Event handler with Reactor. Reactor will dispatch
appropriate callback when event of EventType is received.
@param eh_ Pointer to the EventHandler
@param fd_ File descriptor
@param et_ Event Type
@return true if success, false if error
*/
bool registerIOHandler (EventHandler* eh_,
handler_t fd_,
EventType et_ = RWE_EVENTS);
/** Remove Event handler from reactor for either all I/O events
or timeout event or both. If et_ is TIMEOUT_EVENT, all timers
associated with Event Handler eh_ will be removed.
@param eh_ Pointer to the EventHandler
@param et_ Event Type to remove. Default will remove
Event Handler for all events.
@return true if success, false if wasn't registered for any events.
*/
bool removeHandler (EventHandler* eh_, EventType et_ = ALL_EVENTS);
/** Remove Timer event from the queue. This removes particular event.
@param id_ Timer Id returned by registerTimer.
@return true if timer found and removed; false otherwise
*/
bool removeTimerHandler (TimerId id_);
/** Remove IO Event handler from reactor. This will remove
handler from receiving all I/O events.
@param fd_ File descriptor
@return true on success, false if fd_ is out of range
*/
bool removeIOHandler (handler_t fd_);
/// Main waiting loop that blocks indefinitely processing events.
void waitForEvents (void);
/** Wait for events for time specified. Passing NULL replicates
behavior of waitForEvents(void). Passing tv_ {0, 0} will
cause non-blocking polling for all events. This method
blocks up to tv_ time interval processing event. If an event
occurs, it will process event(s) and return. tv_ time is adjusted
by substracting time spent in event processing.
@param tv_ [RW] is time to wait for.
*/
void waitForEvents (TimeVal* tv_);
/** Stop Reactor's activity. This effectively removes all handlers
from under Reactor's supervision. As of now, there is
no way to re-activate the Reactor. This method is
typically called from method other then EventHandler::signal_handler().
EventHandler::handle_read () is a good candidate.
Calling it from EventHandler::handle_close () will most likely
cause an infinite loop of recursive calls.
*/
void stopReactor (void);
/** Deactivate Reactor. This function sets internal flag which
notifies Reactor's internal event handling loop to abort
its activity. It is mostly used when a *slow* system call is
interrupted by the signal handler. The system call will be
restarted by OS after control returns from the signal handler.
Signal handler (GenServer::handle_signal()) should call this method
to delay Reactor's deactivation.
*/
void deactivate (void);
private:
Reactor (const Reactor&); /// no cloning
Reactor& operator= (const Reactor&); /// no cloning
private:
typedef std::map<u_int, EventHandler*> Fd2Eh_Map_Type;
typedef Fd2Eh_Map_Type::iterator Fd2Eh_Map_Iter;
private:
/// Adjust maxfdp1 in a portable way (win32 ignores maxfd alltogether).
void adjust_maxfdp1 (handler_t fd_);
/// Handle error in select(2) loop appropriately.
bool handleError (void);
/** Notify all EventHandlers registered on respecful events
occured.
@param minimum_ number of file descriptors ready.
*/
bool dispatch (int minimum_);
/// Return number of file descriptors ready accross all sets.
int isAnyReady (void);
/** Check mask for bad file descriptors.
@return true if any fd(s) were found and removed;
false otherwise
*/
bool checkFDs (void);
/** Call handler's callback and, if callback returns negative
value, remove it from the Reactor.
*/
void dispatchHandler ( FdSet& mask_,
Fd2Eh_Map_Type& fdSet_,
EH_IO_Callback callback_);
/** Calculate closest timeout. If TimerQueue is not empty,
then return smallest of maxtimeout and first in the queue.
Otherwise, return maxtimeout.
@param maxwait_ (in) how long we are expected to wait for event(s).
@param howlong_ (out) how long we are going to wait.
*/
void calculateTimeout (TimeVal*& howlong_, TimeVal* maxwait_);
private:
/** Max number of open files per process. This is the soft
limit enforced by the kernel. It can be obtained/manipulated
from the shell with ulimit/limit utilities, but may not
exceed the hard limit.
*/
int m_fd_setsize;
/**
* Max file descriptor number (in all sets) plus 1.
* This value is ignored by WIN32 implementation of select()
*/
handler_t m_maxfd_plus1;
/// Flag that indicates whether Reactor is active or had been stopped.
bool m_active;
/// Event handlers awaiting on READ_EVENT
Fd2Eh_Map_Type m_readSet;
/// Event handlers awaiting on WRITE_EVENT
Fd2Eh_Map_Type m_writeSet;
/// Event handlers awaiting on EXCEPT_EVENT
Fd2Eh_Map_Type m_exceptSet;
/// Handlers to wait for event on
MaskSet m_waitSet;
/// Handlers that are ready for processing
MaskSet m_readySet;
/// The queue of Timers.
TimerQueue m_tqueue;
};
//-----------------------------------------------------------------------------
// Inline functions
//-----------------------------------------------------------------------------
inline void Reactor::deactivate (void) { m_active = false; }
} // end namespace ASSA
#endif /* REACTOR_H */
|