0.4 An Overview of the ACE Toolkit
The ADAPTIVE Communication Environment (ACE) is a widely used example of host infrastructure middleware. The ACE library contains 3240,000 lines of C++ code and 3500 classes. The ACE software distribution also contains hundreds of automated regression tests and example applications. ACE is freely available as open-source software and can be downloaded from http://ace.ece.uci.edu/ or http://www.riverace.com.
To separate concerns, reduce complexity, and permit functional subsetting, ACE is designed using a layered architecture [BMR+96], shown in Figure 0.5. The foundation of the ACE toolkit is its combination of OS adaptation layer and C++ wrapper facades [SSRB00], which encapsulate core OS concurrent network programming mechanisms. The higher layers of ACE build upon this foundation to provide reusable frameworks, networked service components, and standards-based middleware. Together, these middleware layers simplify the creation, composition, configuration, and porting of networked applications without incurring significant performance overhead.
Figure 0.5: The Layered Architecture of ACE
This book focuses on the ACE wrapper facades for native OS IPC and concurrency mechanisms. The additional benefits of frameworks and a comprehensive description of the ACE frameworks are described in the second volume of C++ Network Programming [SH]. The remainder of this chapter outlines the structure and functionality of the various layers in ACE. Section B.1.4 on page 263 describes the standards-based middleware (TAO [SLM98] and JAWS [HS99]) that's based upon and bundled with ACE.
0.4.1 The ACE OS Adaptation Layer
The ACE OS adaptation layer constitutes approximately 10 percent of ACE (about 27,000 lines of code). It consists of a class called ACE_OS that contains over 500 C++ static methods. These methods encapsulate the native, C-oriented OS APIs that hide platform-specific details and expose a uniform interface to OS mechanisms used by higher ACE layers. The ACE_OS adaptation layer simplifies the portability and maintainability of ACE and ensures that only ACE developersnot applications developersmust understand the arcane platform-specific knowledge underlying the ACE wrapper facades. The abstraction provided by the ACE_OSclass enables the use of a single source tree for all the OS platforms shown in Sidebar 1.
Sidebar 1: OS Platforms Supported by ACE
ACE runs on a wide range of operating systems, including:
PCs, for example, Windows (all 32/64-bit versions), WinCE; Redhat, Debian, and SuSE Linux; and Macintosh OS X;
Most versions of UNIX, for example, SunOS 4.x and Solaris, SGI IRIX, HP-UX, Digital UNIX (Compaq Tru64), AIX, DG/UX, SCO OpenServer, UnixWare, NetBSD, and FreeBSD;
Real-time operating systems, for example, VxWorks, OS/9, Chorus, LynxOS, Pharlap TNT, QNX Neutrino and RTP, RTEMS, and pSoS;
Large enterprise systems, for example, OpenVMS, MVS OpenEdi-tion, Tandem NonStop-UX, and Cray UNICOS.
ACE can be used with all of the major C++ compilers on these platforms. The ACE Web site at http://ace.ece.uci.edu contains a complete, up-to-date list of platforms, along with instructions for downloading and building ACE.
0.4.2 The ACE C++ Wrapper Facade Layer
A wrapper facade consists of one or more classes that encapsulate functions and data within a type-safe object-oriented interface [SSRB00]. The ACE C++ wrapper facade layer resides atop its OS adaptation layer and provides largely the same functionality, as shown in Figure 0.5. Packaging this functionality as C++ classes, rather than stand-alone C functions, sig-nificantly reduces the effort required to learn and use ACE correctly. The ACE wrapper facades are designed carefully to minimize or eliminate performance overhead resulting from its increased usability and safety. The principles that guide ACE's design are discussed in Appendix A.
ACE provides an extensive set of wrapper facades, constituting nearly 50 percent of its total source base. Applications combine and refine these wrapper facades by selectively inheriting, aggregating, and/or instantiating them. In this book we show how the socket, file, concurrency, and synchronization wrapper facades are used to develop efficient, portable networked applications.
0.4.3 The ACE Framework Layer
The remaining 340 percent of ACE consists of object-oriented frameworks, which are integrated sets of classes that collaborate to provide a reusable software architecture for a family of related applications [FS97]. Object-oriented frameworks are a key to successful systematic reuse because they complement and amplify other reuse techniques, such as class libraries, components, and patterns [Joh97]. By emphasizing the integration and collaboration of application-specific and application-independent classes, for example, the ACE frameworks enable larger-scale reuse of software than is possible by reusing individual classes or stand-alone functions. The frameworks in ACE integrate and augment its C++ wrapper facade classes by applying advanced concurrency and network programming patterns [BMR+96, SSRB00] to reify the canonical control flow and collaboration among families of related classes in ACE.
The following ACE frameworks support the efficient, robust, and flexible development and configuration of concurrent networked applications and services:
Event demultiplexing and dispatching frameworks. The ACE Reactor and Proactor frameworks implement the Reactor and Proactor patterns [SSRB00], respectively. The Reactor and Proactor frameworks automate the demultiplexing and dispatching of application-specific handlers in response to various types of I/O-based, timer-based, signal-based, and synchronization-based events.
Connection establishment and service initialization framework. The ACE Acceptor-Connector framework implements the Acceptor-Connector pattern [SSRB00]. This framework decouples the active and passive initialization roles from application processing performed by communicating peer services after initialization is complete.
Concurrency framework. ACE provides the Task framework that can be used to implement key concurrency patterns [SSRB00, Lea99], such as Active Object and Half-Sync/Half-Async, which simplify concurrent programming by decoupling method execution from method invocation and decoupling asynchronous and synchronous processing, respectively.
Service configurator framework. This framework implements the Component Configurator pattern [SSRB00] to support the configuration of applications whose services can be assembled dynamically late in their design cycle, for example, at installation time. It also supports the dynamic re-configuration of services in an application at run time.
Streams framework. This framework implements the Pipes and Filters pattern [BMR+96], wherein each processing step is encapsulated in a fil-tering module that can access and manipulate data flowing through the stream of modules. The ACE Streams framework simplifies the development of hierarchically layered services that can be composed flexibly to create certain types of networked applications, such as user-level protocol stacks and network management agents [SS94].
An in-depth discussion of the motivation, design, and use of the frameworks in ACE appears in C++ Network Programming: Systematic Reuse with ACE and Frameworks [SH]. Additional information on the ACE wrapper facades and frameworks is also available in The ACE Programmer's Guide [HJS].
0.4.4 The ACE Networked Service Components Layer
In addition to its host infrastructure middleware wrapper facades and frameworks previously described, ACE also provides a library of networked services that are packaged as components. A component is an encapsulated part of a software system that implements a specific service or set of services [Szy98]. Although these components aren't included in the ACE library itself, they are bundled with the ACE software distribution to provide the following capabilities:
Demonstrate common uses of ACE capabilitiesThe components demonstrate how key ACE frameworks and classes can be used to develop flexible, efficient, and robust networked services.
Factor out reusable networked application building blocksThese components provide reusable implementations of common networked application services, such as naming, event routing [Sch00], logging, time synchronization [SSRB00], and network locking.