
--- Peter Petrov <ppetrov@ppetrov.com> wrote:
My understanding is that the "service repository" is actually only needed for the asynchronous operations.
I think there may be some confusion on this point. Even a hypothetical synchronous-only sockets implementation in asio would still need the "service repository". It occurs to me that I have neglected to mention one other important point about why a demuxer parameter is required, regardless of whether or not the application is making use of async operations: portability. On some systems it is necessary to initialise something before sockets or other I/O objects can be used. Let's take the specific example of Symbian: - The Symbian sockets API is based on BSD sockets, but is presented as a collection of C++ classes (as is the rest of the Symbian programming interface). - Before using sockets, an IPC connection to the socket server (a separate process) must be established. This is achieved by opening an RSocketServ object. - A reference to the socket server must be supplied when opening a socket, i.e.: TInt RSocket::Open(RSocketServ& aServer, ... other args ...); - Similarly, a reference to the socket server must be supplied when opening an RHostResolver object: TInt RHostResolver::Open(RSocketServ& aServer, ... etc ...); Even on Windows it is necessary to initialise Winsock using WSAStartup before socket operations are available. Likewise, when socket operations are no longer required you need to call WSACleanup. With respect to using singletons as a means to address this, leaving design objections aside, Symbian does not allow programs to have global or static data - something I had actually forgotten. :) If the demuxer parameter is not passed to the socket, then portability to operating systems with these requirements would be restricted. So I wonder if the problem is really just one of naming. Specifically, the name of the demuxer class. Asio started life as a library intended for asynchronous use-cases, and for developers with that sort of background I believe the name demuxer (i.e. demultiplexer) is perfectly natural. Now that it has grown into general purpose use, perhaps the name should reflect the expectations of a wider audience. I propose that it could be called something like "io_system". (Other naming suggestions will be appreciated.) Consider the following statements: - An io_system object must be initialised before sockets (or other I/O objects) can be used. See the portability requirement above. - An io_system object is an extensible collection of I/O services (drivers?). - Synchronous operations implicitly run the io_system object for an individual operation. - You must run() the io_system object for it to perform asynchronous operations on your behalf. - You can partition your program by using multiple io_system objects. For asynchronous operations, the fact that a demultiplexer is used is an implementation detail. The public interface of asio does not prohibit an implementation that uses, say, a thread per operation. Given the portability rationale for requiring such a parameter, I can't think of any reasons, be they conceptual, ease-of-use or otherwise, to have a low-level synchronous-only interface. Cheers, Chris