In this tutorial, we're going to extend Tutorial 5 to create a thread-per-connection server. This implementation will create a new thread for each client which connects to us. The ACE_Reactor is still used but only for accepting new connections. The Client_Handler objects won't be registered with the reactor. Instead, they'll be responsible for monitoring their peer() directly.
Abstract:*
We make use of the Strategy Pattern in this example. The ACE_Acceptor inherits form the ACE_Acceptor_Base class which facilitates us to implement various different concurrency strategies depending on whether the server is single-threaded or the server creates a new thread per connection. This also allows us to extend the capabilities of the server in the future by implementing a different strategy.
This information is passed on to the Client_Handler (remember ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > ?). The Client_Handler is an ACE_Svc_Handler as the Svc_Handler is a derivative of the Event_Handler and is associated with ACE_Sock_Stream. It is also derived form the ACE_Task class which allows us to have a thread per connection.
We incorporate the data processing in the svc() method, which will be called per thread for the thread-per-connection server.
Note that here all the Client_Handler objects aren't registered with the reactor. The Reactor is only used to accept client connections. Once a thread has been deicated per connection, the Client Handler object reponsible for that client connection now takes up the job of the reactor and handles future events.
Thus a simple, thread-per-connection server has been built which doesnt delve too deeply into mutli-threading issues.