Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2002-11-27 11:00:05


On Wed, 2002-11-27 at 15:03, Boris Schäling wrote:
> > -----Original Message-----
> > From: boost-bounces_at_[hidden]
> > [mailto:boost-bounces_at_[hidden]]On Behalf Of Hamish Mackenzie
> > Sent: Wednesday, November 27, 2002 12:53 PM
> > To: Boost mailing list
> > Subject: RE: [boost] Re: AW: Re: AW: Sockets
> >
> >
> > 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.
>
> I can't follow. An on_xxx method is always completed before another on_xxx
> method is called. If on_connect() calls writen() and write() in writen()
> returns EWOULDBLOCK that doesn't mean writen() blocks. on_connect() is
> completed, and when the socket descriptor becomes writable the multiplexor
> calls stream::write() as the stream may now ::write() what has been saved
> because of EWOULDBLOCK in a buffer before.

Fair enough but that brings us back to my other point.....
 
> My implementation selects on all file descriptors and calls all on_xxx
> methods that must be called before it selects again on all file descriptors.
> An on_xxx method must complete before another one is called. As every stream
> uses its own buffers, one for reading, one for writing, I still don't see
> any reentrancy problem?

How big is the write buffer? Unlimited? If I loop around in on_connect
calling writen with the contents of the 5GB file where will it all go?
Or for that matter if 100 people connect and each ask to DL a 100MB
file?

> > 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.
>
> You may call writen() several times. If the stream is currently waiting for
> the socket descriptor to become writable the data is saved in the stream's
> buffer. But that doesn't mean writen() blocks.

What if I want to send the set of all odd numbers? We can't have a
buffer big enough for that.

-- 
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