Previous Table of Contents Next


2.3. Understanding ACE

ACE is an object-oriented framework that implements core concurrency and distribution patterns (Schmidt, 1996a) for communication software. ACE provides a rich set of reusable C++ wrappers and framework components that are targeted for developers of high-performance, real-time services and applications across a wide range of OS platforms. The components in ACE provide reusable implementations of the following communication software tasks:

  Connection establishment and service initialization (Schmidt, 1996b)
  Event demultiplexing and event handler dispatching (Harrison, Pyarali, Schmidt, & Jordan, 1997; Schmidt, 1995; Schmidt & Cranor, 1996)
  Interprocess communication (Schmidt et al., 1995) and shared memory management
  Static and dynamic configuration (Jain & Schmidt, 1997; Schmidt & Suda, 1994) of distributed communication services
  Concurrency and synchronization (Lavendar & Schmidt, 1996; Schmidt & Cranor, 1996)
  Distributed services, such as naming, event routing (Harrison, Levine, et al., 1997), logging, time synchronization, and network locking
  Middleware applications, such as high-performance Web servers (Hu, Pyarali, & Schmidt, 1997) and object request brokers (ORBs; Schmidt et al., 1997)

This section outlines the structure of the ACE framework. Section 2.4 illustrates how components and patterns in ACE can be applied to build high-performance, concurrent Web servers.

2.3.1. The Structure of ACE

ACE is a large framework, containing more than 100,000 lines of C++ code divided into about 250 classes. To separate concerns and to reduce the complexity of the frameworks, ACE is designed using a layered architecture. Figure 2.2 illustrates the vertical and horizontal relationships between ACE components.


FIGURE 2.2.  The structure of the components in ACE.

The lower layers of ACE are C++ wrappers that encapsulate core OS communication and concurrency services. The higher layers of ACE extend the C++ wrappers to provide reusable frameworks, self-contained distributed service components, and middleware applications that simplify the creation, composition, and configuration of large-scale communication systems.

2.3.1.1. The ACE C++ Wrapper Layer

Approximately 10% of ACE (that is, approximately 10,000 lines of code) is devoted to the OS adaptation layer, which resides directly atop the native OS APIs written in C. The OS adaptation layer shields the other layers in ACE from platform-specific dependencies associated with the following OS services:

  Concurrency and synchronization. The adaptation layer encapsulates OS concurrency mechanisms for multithreading, multiprocessing, and synchronization.
  Interprocess communication (IPC) and shared memory. The adaptation layer encapsulates common OS mechanisms for local and remote IPC and shared memory.
  Event demultiplexing mechanisms. The adaptation layer encapsulates standard OS mechanisms for demultiplexing I/O-based, timer-based, signal-based, and synchronization-based events.
  Explicit dynamic linking. The adaptation layer encapsulates OS mechanisms for explicit dynamic linking, which allows application services to be configured at installation time or runtime.

The portability provided by the OS adaptation layer enables ACE to run on a wide range of operating systems, including most versions of UNIX, Win32, OpenEdition MVS, and embedded platforms such as VxWorks.

Although it is possible to program directly to the OS adaptation layer, most applications use the C++ wrappers layer, shown in Figure 2.2. ACE C++ wrappers improve application robustness by encapsulating and enhancing the native OS concurrency, communication, memory management, event demultiplexing, and dynamic linking mechanisms with type-safe OO interfaces. This alleviates the need for applications to directly access the underlying OS libraries, which are written using weakly typed C interfaces. Therefore, C++ compilers can detect type system violations at compile time rather than at runtime. ACE uses inlining extensively to eliminate performance penalties that would otherwise be incurred from the additional type-safety and levels of abstraction provided by the OS adaptation layer and the C++ wrappers.

The C++ wrappers provided by ACE are quite extensive, constituting about 50% of the source code. Applications can combine and compose these wrappers by selectively inheriting, aggregating, and/or instantiating the following components:

  Concurrency and synchronization components. ACE abstracts native OS multithreading and multiprocessing mechanisms—such as mutexes and semaphores—to create higher-level OO concurrency abstractions—such as active objects (Lavender & Schmidt, 1996) and polymorphic futures (Halstead, 1985).
  IPC components. These components encapsulate local and/or remote IPC mechanisms (Schmidt et al., 1995) such as sockets, TLI, UNIX FIFOs and STREAM pipes, and Win32 Named Pipes.
  Memory management components. The ACE memory management components provide a flexible and extensible abstraction for managing dynamic allocation and deallocation of shared memory and local memory.


Previous Table of Contents Next