httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Stein <>
Subject Re: cvs commit: apache-2.0/src/main http_protocol.c
Date Thu, 09 Nov 2000 08:20:15 GMT
On Wed, Nov 08, 2000 at 08:52:05PM -0800, wrote:
> On Wed, 8 Nov 2000, Greg Stein wrote:
> > On Wed, Nov 08, 2000 at 07:16:43PM -0800, wrote:
> > > On Wed, 8 Nov 2000, Greg Stein wrote:
> > >...
> > > > PIPE and SOCKET need refcounting, but they cannot be copied. The data
> > > > first be acquired, then it can be copied.
> > > 
> > > We aren't copying data, we are copying the bucket, so the dup function
> > > should just create a second bucket that points to the same
> > > pipe/socket.
> > 
> > That won't work. You can't have two buckets pointing to the same pipe/socket
> > because they cannot each read() the pipe/socket.
> > 
> > If a bucket represents a pipe which is known to have 10 bytes in it before
> > the end-of-pipe (due to whatever protocol), and you copy the bucket, now you
> > have two buckets: one with 10 bytes in it, and one with none. And it all
> > just depends on which order you happen to read them from.
> > 
> > To make it work, the pipe must read [into a heap bucket], then the copy is
> > made. Effectively, if you call copy(), then the pipe will read in a chunk,
> > create a heap bucket (adjust the brigade), then copy the heap bucket. Note
> > that you may still have a pipe bucket remaining (after the newly-created
> > heap bucket), and that bucket may need to be copied further.
> No.  Now you have changed the definition of copy depending on the type of
> the bucket.  That won't work, it makes the API too complex.  If the
> pipe/socket buckets can't be copied until after they have been read, then
> the copy function returns APR_ENOTIMPL.  We don't want the same function
> to mean different things in different situations.

Um. I didn't explain well, then. Defining copy() and split() for PIPEs and
SOCKETs actually simplifies the APIs. Callers don't have to worry about
support or needing to read first or whatever.

Let's say you have a brigade with just PIPE bucket:

          brigade: PIPE

Now you make a copy:

          brigade: HEAP -> PIPE
    copy() result: HEAP

Now, let's say that we say "copy is not implemented on PIPE; read first."

Do a read:

          brigade: HEAP -> PIPE

Do a copy:

          brigade: HEAP -> PIPE
    copy() result: HEAP

I'm suggesting that we define the semantics for copy() on a PIPE to be
exactly that of a read+copy. That will prevent all of the callers from doing
a copy(), seeing the failure, doing a read(), then doing a copy(). No sense
in complicating the life of all copy() callers.

IOW, by saying that PIPE *does* support a copy(), the API stays simple and
the callers don't have to deal with a bunch of variant cases.

Note that it could be said "but copy doesn't copy the whole bucket" is a bad
thing. Well, note that read() also mucks with the brigade. I believe there
is ample reason for saying "you get a copy of the whole bucket if that makes
sense, but some buckets may return a portion" similar to "you can read the
whole bucket if that makes sense, but some buckets may return a portion."

> > To really get this stuff up to top perf, we would want functional copy() and
> > split() operations on all bucket types.
> Again, no.  If the split bucket doesn't make sense for a given bucket
> type, then the split doesn't make sense.  The function will just have to
> deal with a return code of APR_ENOTIMPL.

If I have a PIPE, then it makes sense to say "split at 10 bytse". The result
of the split is two buckets: the first 10 bytes of the PIPE, and the rest of
the PIPE. How does this occur? Well, 10 bytes are read from the PIPE and
form a HEAP bucket; the rest of the PIPE stays the same.

There is a semantic, so lets implement it rather than making callers deal
with the edge cases (buckets that can't split).


Greg Stein,

View raw message