Online Book Reader

Home Category

Beautiful Code [299]

By Root 5093 0
between platforms, but also provide a way to hide the semantic differences as well. These wrappers consist of the three cooperating classes shown in Figure 26-13. The Process class represents a single process and is used to create and synchronize processes. The Process_Options class provides a way to set both platform-independent process options (such as command-line options and environment variables) and platform-specific process options (such as avoiding zombie processes). Finally, the Process_Manager class portably manages the life cycle of groups of processes. We won't cover all the uses of these wrapper facades in this chapter, though they are based on the wrapper facades in ACE. [||||||]It is sufficient to know that not only can processes be created portably on Linux and Windows, but also that I/O handles can be duplicated and passed portably and automatically to the new process.

[||||||]C++ Network Programming, Vol. 1: Mastering Complexity with ACE and Patterns, Douglas C. Schmidt and Stephen D. Huston, Addison-Wesley, 2001.

The design challenge is therefore to accommodate the fact that processes spawned after new connections are accepted will start at the beginning of our program. We certainly don't want child processes to attempt to open a new acceptor and listen for connections of their own; instead, they should listen for data events only on their assigned handle. A naïve solution to this problem would rely on applications to detect this condition and call a special entry point defined in the interface to our process-based Logging_Server class.

Figure 26-13. Portable process wrapper facades

This simple solution, however, is less than ideal. It would require us not only to change the public interface of our process-based Logging_Server, but to expose intimate implementation details to applications, violating encapsulation. A better solution is to override the run( ) template method inherited from the Logging_Server base class, which is passed a copy of the command-line argument by users, to determine whether it has been passed any I/O handles. If not, the process assumes it is a parent and delegates to the base class run( ) method. Otherwise, the process assumes it's a child, so it decodes the handle and calls handle_data( ), as shown in Figure 26-14.

Figure 26-14. Process-per-connection run( ) template method

The remainder of this server implementation is straightforward. As shown in Figure 26-15, the process wrapper facade makes the procedure for spawning our worker processes fairly simple. The implementation for handle_data( ) should be textually identical to that shown in Figure 26-12.

Figure 26-15. Connection handling for the process-per-connection server

Our reimplementation of the run( ) method from the Logging_Server base class allows us to maintain the beautifully simple, straightforward, and uniform invocation used by our other logging servers:

int main (int argc, char *argv[]) {

PPC_Logging_Server server (argc, argv);

server.run ( );

return 0;

}

This main( ) program differs from the thread-per-connection server only in the name of the class that is instantiated and the choice of a Null_Mutex for synchronization. The dispatch of either a parent or a child process is handled transparently by the run( ) method, driven by the command-line arguments passed to the PPC_Logging_Server constructor.

26.4.3. Evaluating the Concurrent Logging Server Solutions

Both concurrent logging servers described in this section significantly enhance the Reactive_Logging_Server and Iterative_Logging_Server in their ability to scale as the number of clients increases by taking leveraging hardware and OS support for multiple threads of execution. It is hard, however, to develop thread-per-connection and process-per-connection concurrency strategies in a platform-agnostic manner. We accomplished this task by using wrapper facades to hide platform differences. Our framework-based server design also provided a common external interface to the Logging_Server class,

Return Main Page Previous Page Next Page

®Online Book Reader