---Greg Stein [mailto:[EMAIL PROTECTED]] said:
> > Precisely. One thing I've been wondering about though... how does the pipe
> > bucket get reinserted as the next bucket if in APR_NONBLOCK_READ mode with 0
> > bytes returned? Does it work right in that case?
>
> Standard operation during read is to convert "self" into a heap bucket with
> data that has been read, then to insert a new bucket *after* "self".
> How are things different if the converted-self has a length of zero bytes?
Right. But because if converted-self has zero bytes, then requeued-after-self
is never even created. Here's a re-annotated copy of the relevant parts of
socket_read():
---------------------------------------------------------------------
static apr_status_t socket_read(apr_bucket *a, const char **str,
apr_size_t *len, apr_read_type_e block)
{
...
rv = apr_recv(p, buf, len);
...
if (rv != APR_SUCCESS && rv != APR_EOF) {
*str = NULL;
free(buf);
return rv; /* Here, self is returned as-is with the error rv */
}
...
/* Self now becomes converted-self, regardless of length */
apr_bucket_heap_make(a, buf, *len, 0, NULL);
/* But wait, if the amount returned from apr_recv() was zero, we never
* create requeued-after-self, regardless of blocking mode!!! This is
* the correct behavior for blocking mode, but not for nonblocking. */
if (*len > 0) {
b = apr_bucket_socket_create(p);
APR_BUCKET_INSERT_AFTER(a, b);
}
else if (rv == APR_EOF && block == APR_NONBLOCK_READ) {
/* we all seem to agree that this little bit is bogus. */
return APR_EOF;
}
return APR_SUCCESS;
}
---------------------------------------------------------------------
Okay, all that in mind, here's how I think the end part of that really OUGHT to
look:
---------------------------------------------------------------------
if (*len > 0) {
apr_bucket_heap_make(a, buf, *len, 0, NULL);
APR_BUCKET_INSERT_AFTER(a, apr_bucket_socket_create(p));
}
else {
apr_bucket_immortal_make(a, "", 0);
if (block == APR_NONBLOCK_READ && rv != APR_EOF) {
APR_BUCKET_INSERT_AFTER(a, apr_bucket_socket_create(p));
}
}
return APR_SUCCESS;
}
---------------------------------------------------------------------
Does this look right?
--Cliff