Comments on the Client/Server Command Line Processor
This solution includes a number of features as well as limitations that will be addressed in later chapters.
- Multiple client processes can connect with the server and perform concurrent requests; each client has a dedicated server (or worker) thread allocated from the thread pool.
- The server and clients can be run from separate command prompts or can be run under control of JobShell (Program 6-3).
- If all the named pipe instances are in use when a client attempts to connect, the new client will wait until a different client disconnects on receiving a $Quit command, making a pipe instance available for another client. Several new clients may be attempting to connect concurrently and will race to open the available instance; any threads that lose this race will need to wait again.
- Each server thread performs synchronous I/O, but some server threads can be processing requests while others are waiting for connections or client requests.
- Extension to networked clients is straightforward, subject to the limitations of named pipes discussed earlier in this chapter. Simply change the pipe names in the header file, or add a client command line parameter for the server name.
- Each server worker thread creates a simple connection thread, which calls ConnectNamedPipe and terminates as soon as a client connects. This allows a worker thread to wait, with a time-out, on the connection thread handle and test the global shutdown flag periodically. If the worker threads blocked on ConnectNamedPipe, they could not test the flag and the server could not shut down. For this reason, the server thread performs a CreateFile on the named pipe in order to force the connection thread to resume and shut down. An alternative would be to use asynchronous I/O (Chapter 14) so that an event could be associated with the ConnectNamedPipe call. The comments in the book's Web site source file provide additional alternatives and information. Without this solution, connection threads might never terminate by themselves, resulting in resource leaks in DLLs. This subject is discussed in Chapter 12.
- There are a number of opportunities to enhance the system. For example, there could be an option to execute an in-process server by using a DLL that implements some of the commands. This enhancement is added in Chapter 12.
- The number of server threads is limited by the WaitForMultipleObjects call in the main thread. While this limitation is easily overcome, the system here is not truly scalable; too many threads will impair performance, as we saw in Chapter 10. Chapter 14 uses asynchronous I/O ports to address this issue.