3.1 Overview
The ACE Reactor framework
simplifies
the development of event-driven programs, which characterize many networked applications. Common sources of events in these applications include activity on an IPC stream for I/O operations, POSIX signals, Windows handle signaling, and timer expirations. In this context, the ACE Reactor framework is responsible for
-
Detecting the occurrence of events from various event sources
-
Demultiplexing
the events to their preregistered event handlers
-
Dispatching to hook
methods
defined by the handlers to process the events in an
application-defined
manner
This chapter describes the following ACE Reactor framework classes that networked applications can use to detect the occurrence of events and then demultiplex and dispatch the events to their event handlers:
|
ACE Class
|
Description
|
|
ACE_Time_Value
|
Provides a portable, normalized representation of time and duration that uses C++ operator overloading to simplify time-
related
arithmetic and relational operations.
|
|
ACE_Event_Handler
|
An abstract class whose interface defines the hook methods that are the target of
ACE_Reactor
callbacks. Most application event handlers developed with ACE are descendants of
ACE_Event_Handler
.
|
|
ACE_Timer_Queue
|
An abstract class defining the capabilities and interface for a timer queue. ACE contains a variety of classes derived from
ACE_Timer_Queue
that provide flexible support for different timing requirements.
|
|
ACE_Reactor
|
Provides the interface for managing event handler registrations and executing the event loop that
drives
event detection, demultiplexing, and dispatching in the Reactor framework.
|
The most important relationships between the classes in the ACE Reactor framework are shown in Figure 3.1. These classes play the following roles in accordance with the Reactor pattern [POSA2]:
Figure 3.1. The ACE Reactor Framework Classes
-
Event infrastructure layer classes
provide application-independent strategies for synchronously detecting and demultiplexing events to event handlers and then dispatching the associated event handler hook methods. The infrastructure layer
components
in the ACE Reactor framework include
ACE_Time_Value
,
ACE_Event_Handler
, the ACE timer queue classes, and the various
implementations
of the
ACE_Reactor
.
-
Application layer classes
define event handlers to perform application-defined processing in their hook methods. In the ACE Reactor framework, application layer classes are descendants of
ACE_Event_Handler
.
The power of the ACE Reactor framework comes from encapsulating the differences between event demultiplexing mechanisms available on various operating systems and maintaining a separation of concerns between framework classes and application classes. By separating application-independent event demultiplexing and dispatching
mechanisms
from application-dependent event processing
policies
, the ACE Reactor framework provides the following benefits:
-
Broad portability.
The framework can be configured to use many OS event demultiplexing mechanisms, such as
select()
(available on UNIX, Windows, and many real-time operating systems),
/dev/poll
(available on certain UNIX platforms), and
WaitForMultipleObjects()
(available only on Windows).
-
Automates event detection, demultiplexing, and dispatching.
By eliminating
reliance
on nonportable native OS event demultiplexing APIs, the ACE Reactor framework provides applications with a uniform object-oriented event detection, demulti-plexing, and dispatching mechanism. Event handler objects can be registered with the
ACE_Reactor
to process various types of events.
-
Transparent extensibility.
The framework employs hook methods via inheritance and dynamic binding to decouple
lower-level event mechanisms
, such as detecting events on multiple I/O handles, expiring timers, and demultiplexing and dispatching methods of the appropriate event handler to process these events, from
higher-level application event processing policies
, such as connection establishment strategies, data marshaling and demarshaling, and processing of client
requests
. This design allows the ACE Reactor framework to be extended
transparently
without modifying existing application code.
-
Increase reuse and minimize errors.
Developers who write programs using native OS event demultiplexing operations must reimplement, debug, and optimize the same low-level code for each application. In contrast, the ACE Reactor framework's event detection, demultiplexing, and dispatching mechanisms are generic and can therefore be reused by many networked applications. This separation of concerns allows developers to focus on high-level application-defined event handler policies, rather than wrestling repeatedly with low-level mechanisms.
-
Efficient event demultiplexing.
The ACE Reactor framework
performs
its event demultiplexing and dispatching logic
efficiently
. For instance, the
ACE_Select_Reactor
presented in Section 4.2 uses the
ACE_Handle_Set_Iterator
wrapper facade class described in Chapter 7 of C++NPv1. This wrapper facade uses an optimized implementation of the Iterator pattern [GoF] to avoid examining
fd_set
bit-masks one bit at a time. This optimization is based on a sophisticated algorithm that uses the C++ exclusive-or operator to reduce run-time complexity from
O(number of total bits)
to
O(number of enabled bits)
, which can improve the run-time performance of large-scale applications substantially.
The remainder of this chapter motivates and describes the capabilities of each class in the ACE Reactor framework. We
illustrate
how this framework can be used to enhance the design of our networked logging server. If you aren't familiar with the Reactor pattern from POSA2, we recommend that you read about it first before delving into the detailed examples in this chapter. Chapter 4 then describes the design and use of the most common implementations of the
ACE_Reactor
interface presented here. That chapter also describes the various concurrency models supported by these
ACE_Reactor
implementations.
|