httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Stein <gst...@lyra.org>
Subject Re: socket_read?
Date Mon, 19 Feb 2001 13:50:43 GMT
On Mon, Feb 19, 2001 at 10:17:31AM +0000, Ben Laurie wrote:
> Greg Stein wrote:
>...
> > IMO, the bucket should transform itself from a pipe/socket to an N-length
> > (heap) bucket when it discovers EOF. But *never* return EOF. The EOF is an
> > "internal" indicator of the bucket.
> > 
> > When you read a bucket with APR_BLOCK_READ, it *must* always read at least
> > one byte. The only reason to not read a byte is if/when the pipe/socket
> > ends, so the bucket should transform to a zero-length heap bucket. If bytes
> > are read, then we use current behavior: transform the bucket to a heap
> > holding N bytes of data, then insert a pipe/socket as the next bucket with
> > the data from the current bucket.
> > 
> > If you read with APR_NONBLOCK_READ, then you may get back zero-length
> > buckets. People who use this reading style should be *VERY* careful: you
> > don't want to loop with NONBLOCK because you could sit there and read
> > zero-length buckets for a long time. Basically, if a NONBLOCK user reads
> > zero-length, then they should switch to BLOCK to read at least one byte,
> > then return to NONBLOCK. If a NONBLOCK pipe/socket bucket hits EOF, then (as
> > usual) a zero-length heap is inserted, but it skips the step of re-inserting
> > a pipe/socket after the heap bucket.
> 
> ??? This would make NONBLOCK completely useless - you would always
> either get input (or EOF) or block waiting for the one byte, making it
> indistinguishable from BLOCK.

Slow down and read my text. I said the BLOCK case should always read a byte.
The NONBLOCK case doesn't.

The bit about the code switching from NONBLOCK to BLOCK is highly dependent
upon what is happening. Sometimes: yes, it would be just like BLOCKing for
that one byte in the first place. But if you're just looking for more work,
then it is totally different; you see nothing and return (i.e. you never
switch over to the BLOCK case).

Point is: I was saying NONBLOCK is useless. I can accept that the user doing
a NONBLOCK and then a BLOCK is useless, though :-)

>...
> Hmm. Actually, now I'm wondering why _anything_ cares about EOF? Surely
> every filter should behave as I described above (in which case, its back
> to a zero-length bucket and APR_SUCCESS all round).
> 
> Actually, now I think about it, that would work fine - since on nonblock
> when EOF is hit, the socket/pipe bucket would not be requeued, so the
> _next_ time round the loop, the brigade will be empty, which is the
> correct EOF indication. So, the fault is that APR_EOF should _never_ be
> returned. Now, all we need to know is why anyone thought it should in
> the first place.

Exactly what I said. Never return EOF. Return zero-length buckets. Don't
requeue if (internally) you hit an EOF.

> > That ought to do the trick. It seems like clean semantics across the board.
> 
> Nope.

Eh? We said the same thing :-)

> So, my next question is: what is the purpose of an EOS bucket? Surely
> its the same as an empty brigade?

Not at all. An empty brigade means "no data in here." An EOS bucket implies
something about the whole stream in which the bucket (and its brigade) are
operating within.

You don't do EOS on a single brigade. It means things on the order of "this
response is complete" or "there is no more input for this request."

You could easily send an empty brigade into the output filter chain.
Useless, but possible. It just means you aren't outputting any data. You
could do a NONBLOCKing read via ap_get_brigade() and get nothing back. The
empty brigade is just signifying "nothing right now." If you call
ap_get_brigade and the resulting brigade had an EOS, then you would *never*
call it again -- you're hit the end of the input stream.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Mime
View raw message