Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2002-11-27 06:52:35


On Tue, 2002-11-26 at 17:12, Boris Schäling wrote:
> > How does the multiplexor know what to pass to write the second time?
>
> The multiplexor doesn't know but the stream does. The multiplexor calls
> stream::write() when the socket descriptor is writable. The stream calls
> ::write() and sends all data which was saved in the stream's buffer because
> of EWOULDBLOCK to the network.
>
> +-------------+ +--------------+ 1) +--------------+
> | multiplexor | 2) | stream |<-------| observer |
> | |<-------| | | |
> | | 3) | | | |
> | |------->| | | |
> +-------------+ +--------------+ +--------------+
>
> 1) observer calls stream::writen() to send data.
> 2) stream calls multiplexor::set_write() because of EWOULDBLOCK.
> 3) multiplexor calls stream::write() when the socket descriptor is writable.

I don't think you have considered the reentrancy issues with this. If
on_connect calls writen and writen simulates blocking (and waits for
more than just writeable on the socket in question) then a second
on_connect (or on_read) comes in then the first on_connect cannot
complete until the second on has.

> > Does the caller have to load the 5GB file into memory before passing it
> > to the write?
>
> The caller may certainly write the file in chunks. Or did I misunderstand
> your question?

Now things start getting really messy. If on_connect calls writen more
than once the second call may be delayed if the an event on a different
socket (or a read event on the same socket comes in) is processed during
the first call to writen. You may have plenty of bandwidth but slow
client will cause a fast one to block.

writen has two possible implementations
1) Wait for just on writeable on the socket in question. In which case
it is indistinguishable from a blocking call.
2) Wait for and process other events to and get yourself into a
reentrancy tangle.

In my opinion the only correct implementation is 1. In which case
writen is a blocking call.

> > What if I want to send a live video stream?
>
> Good point. There is currently no UDP support in my library. Maybe traits
> could be used to tell the stream to discard data that couldn't be written
> immediately? I am not sure if anything else had to be changed for UDP?

This is not the problem I am concerned about. I was trying to
illustrate the problem (as discussed above) that arises when your output
buffer is larger than the amount of information you have to write.

-- 
Hamish Mackenzie <hamish_at_[hidden]>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk