From: Jody Hagins (jody-boost-011304_at_[hidden])
Date: 2005-12-29 11:41:47
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk