From: Aaron W. LaFramboise (aaronrabiddog51_at_[hidden])
Date: 2004-09-12 22:18:05
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'
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
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk