Usage of the shadow field in ngx_buf_t?
brianp at brianp.net
Sun Dec 6 11:34:48 MSK 2009
On Sat, Dec 5, 2009 at 4:06 PM, Brian Pane <brianp at brianp.net> wrote:
> Thanks. What is the right thing to do if a body filter consumes
> only part of a buf and sets aside the rest for later?
By the way, I should note that the best solution I've come up with
so far is:
- In the body filter, make a shallow copy of the chain using
- Each chain link in this copy points to one of the buffers
from the original chain passed into the body filter.
- Leave the "in" chain unmodified, so that the ngx_output_chain
code puts it in the busy list.
- In subsequent calls to the body filter, once the data is finally
consumed, set buf->pos=buf->last. When the current invocation
of the output body filters finishes, ngx_output_chain will call
ngx_chain_update_chains, which will move the busy bufs
to the free list (since buf->pos is finally equal to buf->last
for each buf).
There's a problem, though. This technique works when
one filter does it. But if two or more filters do the same
thing, though, then there's a problem: the first filter in the
chain might set buf->pos=buf->last because it has finished
its processing on the buffer, but the next filter might want
to set aside some or all of the buffer until it receives more
data. The two filters thus end up needing to set buf->pos
to two different values for the same buf.
As a workaround, I suppose each filter that sets aside
buffers could make a copy of each buf, pass the copy
on to the next filter, and then (after the next filter returns)
update the original buf based on how much of the copy
buf the next filters have consumed. (Could I use the
buf->shadow field in the copy buf to hold the pointer
to the original?)
But it seems like this is a problem that other people
may have solved already, so if there's an existing
solution, I'd rather use that instead of inventing a
More information about the nginx-devel