
Carlo Wood wrote:
2. It is unavoidable that this library uses threads.
I disagree strongly. I think spawning additional threads is both unnecessary and undesirable.
1) On windows we have a limitation of at most 64 'Event' objects that can be 'waited' for at a time. This is not enough for large server applications that might need thousands of TCP/IP sockets.
In the case of sockets, Winsock has other mechanisms for scaling in this respect, such as I/O completion routines. On pre-Winsock2 platforms, which hopefully are dwindling, I don't think falling back to the 64 handle limit will be a problem. It seems unlikely to me that there are many cases were the limit would be exceeded. However, in those cases, I don't think it would be a problem if the multiplex user were required to create another thread, and another multiplex. I don't think the multiplex should do this.
2) On windows there are different types of handles/events. It seems to make a lot more sense to use different threads to wait for different types. For example, there is a WSAWaitForMultipleObjects (for sockets) and a WaitForMultipleObjects that allows one to wait for arbitrary events (but not socket events(?)). More in general however - there seems to be a need to use different ways to demultiplex and handle different types - even if the handles of all different types are the same (ie, 'int' on UNIX). Consider the major difference between a listen socket, a very busy UDP socket and a very busy memory mapped filedescriptor. It might be easier to regular priority issues between the different types by putting their dispatchers in separate threads. Note however that I DO think that the callback functions for each event (that is, the moment we start calling IOstream functions) should happen in the same thread again; this new library should shield the use of threads for the user as much as possible!
I also don't think the multiplex should do this. Boost shouldn't second-guess what the user is trying to do. If the user knows he needs two separate threads to handle two separate resources, then let the user create two threads and put a multiplex in each. By _multiplex_ I mean the class (or whatever entity) that implements the core of the demultiplexing of various resources. (I'm using this name because thats what I called it in my own library.) I beleive this class should have these characteristics: 1) Minimal - It should handle every sort of event that might need to be handled, but nothing more. More complex logic, such as pooling and balancing, should be handled elsewhere, possibly by a derived class. In addition, the design should be as unsophisticated as possible. In particular, event notification might be simple functors (no 'observer' frameworks) 2) Efficient - For many applications, performance will be paramount. Many asynchronous algorithms will depend on the multiplex core having negligable overhead, and Boost should not disappoint. As it may be a crucial building block of nearly any real-world program, it should also be storage efficient, to not rule out application in embedded areas. 3) Compatible - See http://article.gmane.org/gmane.comp.lib.boost.devel/109475 It is my opinion, in fact, that this multiplex class should be in its own library, isolated from any other particular library that would depend on it. In other words, it wouldn't be any more coupled with I/O than it would be with Boost.Thread or date_time. Aaron W. LaFramboise