httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Laurie <>
Subject Re: socket_read?
Date Mon, 19 Feb 2001 10:17:31 GMT
Greg Stein wrote:
> I thought of the (possible) reason earlier tonite.
> If you read and get back len==0, then how do you distinguish between "none
> available (yet)" and "you won't get any more."
> I believe the current code says "APR_EOF means you won't get any more;
> otherwise, the len is what is available right now."
> 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. I think you have to return a zero-length
bucket _and_ EOF, so you can tell that its EOF without blocking if it
isn't. That means, of course, that in the blocking case, we should do
the same. Hmm. But then the caller will have to treat EOF as a success
case. Blimey, I'm in danger of working myself around to thinking the
existing code is the right way to do it.

Ah! I have it. What should happen is we should have an EOF bucket, that
(if read) is zero length. Reading returns APR_SUCCESS, but you can test
for it with APR_BUCKET_IS_EOF(pbkt) (_after_ the read!).

In fact, in mod_tls, I should not assume that the underlying filter is a
socket, so I shouldn't be testing for EOF anyway - I should simply
return EOS when the brigade is empty.

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.

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


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




"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

View raw message