
Looking at asio::demuxer... I see that run() can be called from multiple threads. To see how that is done (there are many ways), I took a quick peek at the source. After the last email, I was not surprised to see an explicit mutex. Pertaining to my last post, this should probably be a policy so that a null mutex can be used (or some other mechanism for saying that this demuxer is single threaded). I took a brief look at the epoll implementation. I don't see EPOLLET anywhere, so you are doing Level Triggered. Curious why not Edge Triggered? I imagine the reason is to prevent the implementation from having to either keep track of the FD still being ready (until EAGAIN) or keeping its own internal buffer to hold the "overflow" but I'm still curious. It seems a framework like this is good for ET since it can take care of the added complexities. epoll_ctl() will return EEXIST if the fd is alredy registered, though it is possible to have it succeeed if called from separate threads. It shouldn't matter, though. However, of some concern is the fact that you call epoll_wait() from multiple threads using the same epoll fd. Assume N different threads are blocked on epoll_wait(). Data arrives. All N threads will be notified of the data available. All N threads will then try to read from the sockets. Bad performance issues. Worse, if a socket in not NBLOCK, all the threads hang reading the same socket. I'm also curious as to to manner in which the FDs are inserted/removed from the epoll mechanism. This may go to the overall design. I see the benefit in saying "read X bytes and let me know when they arrive." However, I would think a more common case, for long TCP/IP sessions would be, "keep reading until I tell you to stop, and let me know when each chunk of data arrives." I do not see an interface for the latter, though I'm sure it's there... Also, it seems a waste to call epoll_ctl() after each I/O operation, regardless of whether it will change the events. Before I severely overstep, can you point me to a good example of async_read operations? I see this as a the primary use case, yet it does not appear in any of the tutorials. async_read() does not provide the buffer to the handler. It seems the only way to use it is with a function object that contains the buffer. Is that a correct understanding, or do I just need to go back to sleep? It would be nice if the refrence web pages had a link to the source. I'd like to confirm what I see in the doc with what the source says. Maybe even another set of pages that are annotated with the implementation source code.