|
|
|
Dispatcher
- I/O Event Dispatcher
The Dispatcher
class implements an I/O event dispatcher, which
monitors file descriptors for I/O activity. Applications that use a dispatcher
are generally structured as follows:
Perform application-specific initialization. Register event handlers with the dispatcher. DO forever Wait for the next event. Execute the handler bound to the event. ENDDO
The event processing loop is encapsulated in the dispatcher's
Monitor()
method.
Applications can:
dispatcher.Register (fd, InputPending|OutputReady|Exceptional, handler) ;When an I/O event is detected on the handler's source (i.e., a file descriptor), the dispatcher invokes the handler's
operator()
method to respond to the event. Applications can register handlers for
any one or a combination of the following I/O events: input-pending,
output-ready, and exceptional-input-pending.
dispatcher.Register (numSeconds, handler) ;When the specified time interval has elapsed, the dispatcher invokes the handler's
operator()
method to react to the timeout.
dispatcher.Register (handler) ;When no I/O is active and no timers are ready to fire, the dispatcher invokes the
operator()
method of the next idle "task" in
the queue. Idle tasks are used for "background" processing.
An application can declare event handlers in either of two ways. First,
the application can declare a subclass of the DxEventHandler
base class and create instances of the subclass. In the following example,
the application creates a periodic timer (i.e., the handler re-registers
itself every time it fires):
#include "Dispatcher.h" // Dispatcher class definitions. class TimeoutHandler : public DxEventHandler { public: TimeoutHandler (double numSeconds) { timeout = numSeconds ; } int operator() (Dispatcher& dispatcher, int eventMask) { ... process timeout ... dispatcher.Register (timeout, *this) ; } private: double timeout ; } int main (...) { Dispatcher dispatcher ; TimeoutHandler timer (30.0) ; // Every 30 seconds. dispatcher.Register (30.0, timer) ; // Register timer. dispatcher.Monitor () ; // Monitor events. }
If creating DxEventHandler
subclasses seems like too much
trouble, you can register callback functions instead, using the
Callback
class defined in "Dispatcher.h
".
In the following example, a callback function, ReadInput()
,
is bound to input-pending events on standard input:
#include <cstdio> // Dispatcher class definitions. #include "Dispatcher.h" // Dispatcher class definitions. static int ReadInput (Dispatcher& dispatcher, DxEventHandler& handler, int eventMask, void *argument) { char buffer[128] ; fgets (buffer, sizeof buffer, (FILE *) argument) ; printf ("(ReadInput) %s\n", buffer) ; return (0) ; } int main (...) { // Create I/O handler. Callback handler (ReadInput, (void *) stdin) ; Dispatcher dispatcher ; // Register I/O handler. dispatcher.Register (fileno (stdin), Dispatcher::InputPending, handler) ; dispatcher.Monitor () ; // Monitor events. }
Dispatcher()
- creates an I/O dispatcher.
~Dispatcher()
- destroys a dispatcher.
Register()
- registers an idle task with the dispatcher.
Register()
- registers an I/O handler with the dispatcher.
Register()
- registers a timeout handler with the dispatcher.
Monitor()
- monitors and responds to I/O events and timeouts.
Unregister()
- removes a registered handler.
Dispatcher.C
Dispatcher.h