1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev#include <ngx_event.h>
11e18a033bSKonstantin Ananyev#include <ngx_event_pipe.h>
12e18a033bSKonstantin Ananyev
13e18a033bSKonstantin Ananyev
14e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p);
15e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p);
16e18a033bSKonstantin Ananyev
17e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p);
18e18a033bSKonstantin Ananyevstatic ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf);
19e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p);
20e18a033bSKonstantin Ananyev
21e18a033bSKonstantin Ananyev
22e18a033bSKonstantin Ananyevngx_int_t
23e18a033bSKonstantin Ananyevngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
24e18a033bSKonstantin Ananyev{
25e18a033bSKonstantin Ananyev    ngx_int_t     rc;
26e18a033bSKonstantin Ananyev    ngx_uint_t    flags;
27e18a033bSKonstantin Ananyev    ngx_event_t  *rev, *wev;
28e18a033bSKonstantin Ananyev
29e18a033bSKonstantin Ananyev    for ( ;; ) {
30e18a033bSKonstantin Ananyev        if (do_write) {
31e18a033bSKonstantin Ananyev            p->log->action = "sending to client";
32e18a033bSKonstantin Ananyev
33e18a033bSKonstantin Ananyev            rc = ngx_event_pipe_write_to_downstream(p);
34e18a033bSKonstantin Ananyev
35e18a033bSKonstantin Ananyev            if (rc == NGX_ABORT) {
36e18a033bSKonstantin Ananyev                return NGX_ABORT;
37e18a033bSKonstantin Ananyev            }
38e18a033bSKonstantin Ananyev
39e18a033bSKonstantin Ananyev            if (rc == NGX_BUSY) {
40e18a033bSKonstantin Ananyev                return NGX_OK;
41e18a033bSKonstantin Ananyev            }
42e18a033bSKonstantin Ananyev        }
43e18a033bSKonstantin Ananyev
44e18a033bSKonstantin Ananyev        p->read = 0;
45e18a033bSKonstantin Ananyev        p->upstream_blocked = 0;
46e18a033bSKonstantin Ananyev
47e18a033bSKonstantin Ananyev        p->log->action = "reading upstream";
48e18a033bSKonstantin Ananyev
49e18a033bSKonstantin Ananyev        if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) {
50e18a033bSKonstantin Ananyev            return NGX_ABORT;
51e18a033bSKonstantin Ananyev        }
52e18a033bSKonstantin Ananyev
53e18a033bSKonstantin Ananyev        if (!p->read && !p->upstream_blocked) {
54e18a033bSKonstantin Ananyev            break;
55e18a033bSKonstantin Ananyev        }
56e18a033bSKonstantin Ananyev
57e18a033bSKonstantin Ananyev        do_write = 1;
58e18a033bSKonstantin Ananyev    }
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev    if (p->upstream->fd != (ngx_socket_t) -1) {
61e18a033bSKonstantin Ananyev        rev = p->upstream->read;
62e18a033bSKonstantin Ananyev
63e18a033bSKonstantin Ananyev        flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0;
64e18a033bSKonstantin Ananyev
65e18a033bSKonstantin Ananyev        if (ngx_handle_read_event(rev, flags) != NGX_OK) {
66e18a033bSKonstantin Ananyev            return NGX_ABORT;
67e18a033bSKonstantin Ananyev        }
68e18a033bSKonstantin Ananyev
69e18a033bSKonstantin Ananyev        if (!rev->delayed) {
70e18a033bSKonstantin Ananyev            if (rev->active && !rev->ready) {
71e18a033bSKonstantin Ananyev                ngx_add_timer(rev, p->read_timeout);
72e18a033bSKonstantin Ananyev
73e18a033bSKonstantin Ananyev            } else if (rev->timer_set) {
74e18a033bSKonstantin Ananyev                ngx_del_timer(rev);
75e18a033bSKonstantin Ananyev            }
76e18a033bSKonstantin Ananyev        }
77e18a033bSKonstantin Ananyev    }
78e18a033bSKonstantin Ananyev
79e18a033bSKonstantin Ananyev    if (p->downstream->fd != (ngx_socket_t) -1
80e18a033bSKonstantin Ananyev        && p->downstream->data == p->output_ctx)
81e18a033bSKonstantin Ananyev    {
82e18a033bSKonstantin Ananyev        wev = p->downstream->write;
83e18a033bSKonstantin Ananyev        if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
84e18a033bSKonstantin Ananyev            return NGX_ABORT;
85e18a033bSKonstantin Ananyev        }
86e18a033bSKonstantin Ananyev
87e18a033bSKonstantin Ananyev        if (!wev->delayed) {
88e18a033bSKonstantin Ananyev            if (wev->active && !wev->ready) {
89e18a033bSKonstantin Ananyev                ngx_add_timer(wev, p->send_timeout);
90e18a033bSKonstantin Ananyev
91e18a033bSKonstantin Ananyev            } else if (wev->timer_set) {
92e18a033bSKonstantin Ananyev                ngx_del_timer(wev);
93e18a033bSKonstantin Ananyev            }
94e18a033bSKonstantin Ananyev        }
95e18a033bSKonstantin Ananyev    }
96e18a033bSKonstantin Ananyev
97e18a033bSKonstantin Ananyev    return NGX_OK;
98e18a033bSKonstantin Ananyev}
99e18a033bSKonstantin Ananyev
100e18a033bSKonstantin Ananyev
101e18a033bSKonstantin Ananyevstatic ngx_int_t
102e18a033bSKonstantin Ananyevngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
103e18a033bSKonstantin Ananyev{
104e18a033bSKonstantin Ananyev    off_t         limit;
105e18a033bSKonstantin Ananyev    ssize_t       n, size;
106e18a033bSKonstantin Ananyev    ngx_int_t     rc;
107e18a033bSKonstantin Ananyev    ngx_buf_t    *b;
108e18a033bSKonstantin Ananyev    ngx_msec_t    delay;
109e18a033bSKonstantin Ananyev    ngx_chain_t  *chain, *cl, *ln;
110e18a033bSKonstantin Ananyev
111e18a033bSKonstantin Ananyev    if (p->upstream_eof || p->upstream_error || p->upstream_done) {
112e18a033bSKonstantin Ananyev        return NGX_OK;
113e18a033bSKonstantin Ananyev    }
114e18a033bSKonstantin Ananyev
115e18a033bSKonstantin Ananyev#if (NGX_THREADS)
116e18a033bSKonstantin Ananyev
117e18a033bSKonstantin Ananyev    if (p->aio) {
118e18a033bSKonstantin Ananyev        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
119e18a033bSKonstantin Ananyev                       "pipe read upstream: aio");
120e18a033bSKonstantin Ananyev        return NGX_AGAIN;
121e18a033bSKonstantin Ananyev    }
122e18a033bSKonstantin Ananyev
123e18a033bSKonstantin Ananyev    if (p->writing) {
124e18a033bSKonstantin Ananyev        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
125e18a033bSKonstantin Ananyev                       "pipe read upstream: writing");
126e18a033bSKonstantin Ananyev
127e18a033bSKonstantin Ananyev        rc = ngx_event_pipe_write_chain_to_temp_file(p);
128e18a033bSKonstantin Ananyev
129e18a033bSKonstantin Ananyev        if (rc != NGX_OK) {
130e18a033bSKonstantin Ananyev            return rc;
131e18a033bSKonstantin Ananyev        }
132e18a033bSKonstantin Ananyev    }
133e18a033bSKonstantin Ananyev
134e18a033bSKonstantin Ananyev#endif
135e18a033bSKonstantin Ananyev
136e18a033bSKonstantin Ananyev    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
137e18a033bSKonstantin Ananyev                   "pipe read upstream: %d", p->upstream->read->ready);
138e18a033bSKonstantin Ananyev
139e18a033bSKonstantin Ananyev    for ( ;; ) {
140e18a033bSKonstantin Ananyev
141e18a033bSKonstantin Ananyev        if (p->upstream_eof || p->upstream_error || p->upstream_done) {
142e18a033bSKonstantin Ananyev            break;
143e18a033bSKonstantin Ananyev        }
144e18a033bSKonstantin Ananyev
145e18a033bSKonstantin Ananyev        if (p->preread_bufs == NULL && !p->upstream->read->ready) {
146e18a033bSKonstantin Ananyev            break;
147e18a033bSKonstantin Ananyev        }
148e18a033bSKonstantin Ananyev
149e18a033bSKonstantin Ananyev        if (p->preread_bufs) {
150e18a033bSKonstantin Ananyev
151e18a033bSKonstantin Ananyev            /* use the pre-read bufs if they exist */
152e18a033bSKonstantin Ananyev
153e18a033bSKonstantin Ananyev            chain = p->preread_bufs;
154e18a033bSKonstantin Ananyev            p->preread_bufs = NULL;
155e18a033bSKonstantin Ananyev            n = p->preread_size;
156e18a033bSKonstantin Ananyev
157e18a033bSKonstantin Ananyev            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
158e18a033bSKonstantin Ananyev                           "pipe preread: %z", n);
159e18a033bSKonstantin Ananyev
160e18a033bSKonstantin Ananyev            if (n) {
161e18a033bSKonstantin Ananyev                p->read = 1;
162e18a033bSKonstantin Ananyev            }
163e18a033bSKonstantin Ananyev
164e18a033bSKonstantin Ananyev        } else {
165e18a033bSKonstantin Ananyev
166e18a033bSKonstantin Ananyev#if (NGX_HAVE_KQUEUE)
167e18a033bSKonstantin Ananyev
168e18a033bSKonstantin Ananyev            /*
169e18a033bSKonstantin Ananyev             * kqueue notifies about the end of file or a pending error.
170e18a033bSKonstantin Ananyev             * This test allows not to allocate a buf on these conditions
171e18a033bSKonstantin Ananyev             * and not to call c->recv_chain().
172e18a033bSKonstantin Ananyev             */
173e18a033bSKonstantin Ananyev
174e18a033bSKonstantin Ananyev            if (p->upstream->read->available == 0
175e18a033bSKonstantin Ananyev                && p->upstream->read->pending_eof)
176e18a033bSKonstantin Ananyev            {
177e18a033bSKonstantin Ananyev                p->upstream->read->ready = 0;
178e18a033bSKonstantin Ananyev                p->upstream->read->eof = 1;
179e18a033bSKonstantin Ananyev                p->upstream_eof = 1;
180e18a033bSKonstantin Ananyev                p->read = 1;
181e18a033bSKonstantin Ananyev
182e18a033bSKonstantin Ananyev                if (p->upstream->read->kq_errno) {
183e18a033bSKonstantin Ananyev                    p->upstream->read->error = 1;
184e18a033bSKonstantin Ananyev                    p->upstream_error = 1;
185e18a033bSKonstantin Ananyev                    p->upstream_eof = 0;
186e18a033bSKonstantin Ananyev
187e18a033bSKonstantin Ananyev                    ngx_log_error(NGX_LOG_ERR, p->log,
188e18a033bSKonstantin Ananyev                                  p->upstream->read->kq_errno,
189e18a033bSKonstantin Ananyev                                  "kevent() reported that upstream "
190e18a033bSKonstantin Ananyev                                  "closed connection");
191e18a033bSKonstantin Ananyev                }
192e18a033bSKonstantin Ananyev
193e18a033bSKonstantin Ananyev                break;
194e18a033bSKonstantin Ananyev            }
195e18a033bSKonstantin Ananyev#endif
196e18a033bSKonstantin Ananyev
197e18a033bSKonstantin Ananyev            if (p->limit_rate) {
198e18a033bSKonstantin Ananyev                if (p->upstream->read->delayed) {
199e18a033bSKonstantin Ananyev                    break;
200e18a033bSKonstantin Ananyev                }
201e18a033bSKonstantin Ananyev
202e18a033bSKonstantin Ananyev                limit = (off_t) p->limit_rate * (ngx_time() - p->start_sec + 1)
203e18a033bSKonstantin Ananyev                        - p->read_length;
204e18a033bSKonstantin Ananyev
205e18a033bSKonstantin Ananyev                if (limit <= 0) {
206e18a033bSKonstantin Ananyev                    p->upstream->read->delayed = 1;
207e18a033bSKonstantin Ananyev                    delay = (ngx_msec_t) (- limit * 1000 / p->limit_rate + 1);
208e18a033bSKonstantin Ananyev                    ngx_add_timer(p->upstream->read, delay);
209e18a033bSKonstantin Ananyev                    break;
210e18a033bSKonstantin Ananyev                }
211e18a033bSKonstantin Ananyev
212e18a033bSKonstantin Ananyev            } else {
213e18a033bSKonstantin Ananyev                limit = 0;
214e18a033bSKonstantin Ananyev            }
215e18a033bSKonstantin Ananyev
216e18a033bSKonstantin Ananyev            if (p->free_raw_bufs) {
217e18a033bSKonstantin Ananyev
218e18a033bSKonstantin Ananyev                /* use the free bufs if they exist */
219e18a033bSKonstantin Ananyev
220e18a033bSKonstantin Ananyev                chain = p->free_raw_bufs;
221e18a033bSKonstantin Ananyev                if (p->single_buf) {
222e18a033bSKonstantin Ananyev                    p->free_raw_bufs = p->free_raw_bufs->next;
223e18a033bSKonstantin Ananyev                    chain->next = NULL;
224e18a033bSKonstantin Ananyev                } else {
225e18a033bSKonstantin Ananyev                    p->free_raw_bufs = NULL;
226e18a033bSKonstantin Ananyev                }
227e18a033bSKonstantin Ananyev
228e18a033bSKonstantin Ananyev            } else if (p->allocated < p->bufs.num) {
229e18a033bSKonstantin Ananyev
230e18a033bSKonstantin Ananyev                /* allocate a new buf if it's still allowed */
231e18a033bSKonstantin Ananyev
232e18a033bSKonstantin Ananyev                b = ngx_create_temp_buf(p->pool, p->bufs.size);
233e18a033bSKonstantin Ananyev                if (b == NULL) {
234e18a033bSKonstantin Ananyev                    return NGX_ABORT;
235e18a033bSKonstantin Ananyev                }
236e18a033bSKonstantin Ananyev
237e18a033bSKonstantin Ananyev                p->allocated++;
238e18a033bSKonstantin Ananyev
239e18a033bSKonstantin Ananyev                chain = ngx_alloc_chain_link(p->pool);
240e18a033bSKonstantin Ananyev                if (chain == NULL) {
241e18a033bSKonstantin Ananyev                    return NGX_ABORT;
242e18a033bSKonstantin Ananyev                }
243e18a033bSKonstantin Ananyev
244e18a033bSKonstantin Ananyev                chain->buf = b;
245e18a033bSKonstantin Ananyev                chain->next = NULL;
246e18a033bSKonstantin Ananyev
247e18a033bSKonstantin Ananyev            } else if (!p->cacheable
248e18a033bSKonstantin Ananyev                       && p->downstream->data == p->output_ctx
249e18a033bSKonstantin Ananyev                       && p->downstream->write->ready
250e18a033bSKonstantin Ananyev                       && !p->downstream->write->delayed)
251e18a033bSKonstantin Ananyev            {
252e18a033bSKonstantin Ananyev                /*
253e18a033bSKonstantin Ananyev                 * if the bufs are not needed to be saved in a cache and
254e18a033bSKonstantin Ananyev                 * a downstream is ready then write the bufs to a downstream
255e18a033bSKonstantin Ananyev                 */
256e18a033bSKonstantin Ananyev
257e18a033bSKonstantin Ananyev                p->upstream_blocked = 1;
258e18a033bSKonstantin Ananyev
259e18a033bSKonstantin Ananyev                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
260e18a033bSKonstantin Ananyev                               "pipe downstream ready");
261e18a033bSKonstantin Ananyev
262e18a033bSKonstantin Ananyev                break;
263e18a033bSKonstantin Ananyev
264e18a033bSKonstantin Ananyev            } else if (p->cacheable
265e18a033bSKonstantin Ananyev                       || p->temp_file->offset < p->max_temp_file_size)
266e18a033bSKonstantin Ananyev            {
267e18a033bSKonstantin Ananyev
268e18a033bSKonstantin Ananyev                /*
269e18a033bSKonstantin Ananyev                 * if it is allowed, then save some bufs from p->in
270e18a033bSKonstantin Ananyev                 * to a temporary file, and add them to a p->out chain
271e18a033bSKonstantin Ananyev                 */
272e18a033bSKonstantin Ananyev
273e18a033bSKonstantin Ananyev                rc = ngx_event_pipe_write_chain_to_temp_file(p);
274e18a033bSKonstantin Ananyev
275e18a033bSKonstantin Ananyev                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
276e18a033bSKonstantin Ananyev                               "pipe temp offset: %O", p->temp_file->offset);
277e18a033bSKonstantin Ananyev
278e18a033bSKonstantin Ananyev                if (rc == NGX_BUSY) {
279e18a033bSKonstantin Ananyev                    break;
280e18a033bSKonstantin Ananyev                }
281e18a033bSKonstantin Ananyev
282e18a033bSKonstantin Ananyev                if (rc != NGX_OK) {
283e18a033bSKonstantin Ananyev                    return rc;
284e18a033bSKonstantin Ananyev                }
285e18a033bSKonstantin Ananyev
286e18a033bSKonstantin Ananyev                chain = p->free_raw_bufs;
287e18a033bSKonstantin Ananyev                if (p->single_buf) {
288e18a033bSKonstantin Ananyev                    p->free_raw_bufs = p->free_raw_bufs->next;
289e18a033bSKonstantin Ananyev                    chain->next = NULL;
290e18a033bSKonstantin Ananyev                } else {
291e18a033bSKonstantin Ananyev                    p->free_raw_bufs = NULL;
292e18a033bSKonstantin Ananyev                }
293e18a033bSKonstantin Ananyev
294e18a033bSKonstantin Ananyev            } else {
295e18a033bSKonstantin Ananyev
296e18a033bSKonstantin Ananyev                /* there are no bufs to read in */
297e18a033bSKonstantin Ananyev
298e18a033bSKonstantin Ananyev                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
299e18a033bSKonstantin Ananyev                               "no pipe bufs to read in");
300e18a033bSKonstantin Ananyev
301e18a033bSKonstantin Ananyev                break;
302e18a033bSKonstantin Ananyev            }
303e18a033bSKonstantin Ananyev
304e18a033bSKonstantin Ananyev            n = p->upstream->recv_chain(p->upstream, chain, limit);
305e18a033bSKonstantin Ananyev
306e18a033bSKonstantin Ananyev            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
307e18a033bSKonstantin Ananyev                           "pipe recv chain: %z", n);
308e18a033bSKonstantin Ananyev
309e18a033bSKonstantin Ananyev            if (p->free_raw_bufs) {
310e18a033bSKonstantin Ananyev                chain->next = p->free_raw_bufs;
311e18a033bSKonstantin Ananyev            }
312e18a033bSKonstantin Ananyev            p->free_raw_bufs = chain;
313e18a033bSKonstantin Ananyev
314e18a033bSKonstantin Ananyev            if (n == NGX_ERROR) {
315e18a033bSKonstantin Ananyev                p->upstream_error = 1;
316e18a033bSKonstantin Ananyev                break;
317e18a033bSKonstantin Ananyev            }
318e18a033bSKonstantin Ananyev
319e18a033bSKonstantin Ananyev            if (n == NGX_AGAIN) {
320e18a033bSKonstantin Ananyev                if (p->single_buf) {
321e18a033bSKonstantin Ananyev                    ngx_event_pipe_remove_shadow_links(chain->buf);
322e18a033bSKonstantin Ananyev                }
323e18a033bSKonstantin Ananyev
324e18a033bSKonstantin Ananyev                break;
325e18a033bSKonstantin Ananyev            }
326e18a033bSKonstantin Ananyev
327e18a033bSKonstantin Ananyev            p->read = 1;
328e18a033bSKonstantin Ananyev
329e18a033bSKonstantin Ananyev            if (n == 0) {
330e18a033bSKonstantin Ananyev                p->upstream_eof = 1;
331e18a033bSKonstantin Ananyev                break;
332e18a033bSKonstantin Ananyev            }
333e18a033bSKonstantin Ananyev        }
334e18a033bSKonstantin Ananyev
335e18a033bSKonstantin Ananyev        delay = p->limit_rate ? (ngx_msec_t) n * 1000 / p->limit_rate : 0;
336e18a033bSKonstantin Ananyev
337e18a033bSKonstantin Ananyev        p->read_length += n;
338e18a033bSKonstantin Ananyev        cl = chain;
339e18a033bSKonstantin Ananyev        p->free_raw_bufs = NULL;
340e18a033bSKonstantin Ananyev
341e18a033bSKonstantin Ananyev        while (cl && n > 0) {
342e18a033bSKonstantin Ananyev
343e18a033bSKonstantin Ananyev            ngx_event_pipe_remove_shadow_links(cl->buf);
344e18a033bSKonstantin Ananyev
345e18a033bSKonstantin Ananyev            size = cl->buf->end - cl->buf->last;
346e18a033bSKonstantin Ananyev
347e18a033bSKonstantin Ananyev            if (n >= size) {
348e18a033bSKonstantin Ananyev                cl->buf->last = cl->buf->end;
349e18a033bSKonstantin Ananyev
350e18a033bSKonstantin Ananyev                /* STUB */ cl->buf->num = p->num++;
351e18a033bSKonstantin Ananyev
352e18a033bSKonstantin Ananyev                if (p->input_filter(p, cl->buf) == NGX_ERROR) {
353e18a033bSKonstantin Ananyev                    return NGX_ABORT;
354e18a033bSKonstantin Ananyev                }
355e18a033bSKonstantin Ananyev
356e18a033bSKonstantin Ananyev                n -= size;
357e18a033bSKonstantin Ananyev                ln = cl;
358e18a033bSKonstantin Ananyev                cl = cl->next;
359e18a033bSKonstantin Ananyev                ngx_free_chain(p->pool, ln);
360e18a033bSKonstantin Ananyev
361e18a033bSKonstantin Ananyev            } else {
362e18a033bSKonstantin Ananyev                cl->buf->last += n;
363e18a033bSKonstantin Ananyev                n = 0;
364e18a033bSKonstantin Ananyev            }
365e18a033bSKonstantin Ananyev        }
366e18a033bSKonstantin Ananyev
367e18a033bSKonstantin Ananyev        if (cl) {
368e18a033bSKonstantin Ananyev            for (ln = cl; ln->next; ln = ln->next) { /* void */ }
369e18a033bSKonstantin Ananyev
370e18a033bSKonstantin Ananyev            ln->next = p->free_raw_bufs;
371e18a033bSKonstantin Ananyev            p->free_raw_bufs = cl;
372e18a033bSKonstantin Ananyev        }
373e18a033bSKonstantin Ananyev
374e18a033bSKonstantin Ananyev        if (delay > 0) {
375e18a033bSKonstantin Ananyev            p->upstream->read->delayed = 1;
376e18a033bSKonstantin Ananyev            ngx_add_timer(p->upstream->read, delay);
377e18a033bSKonstantin Ananyev            break;
378e18a033bSKonstantin Ananyev        }
379e18a033bSKonstantin Ananyev    }
380e18a033bSKonstantin Ananyev
381e18a033bSKonstantin Ananyev#if (NGX_DEBUG)
382e18a033bSKonstantin Ananyev
383e18a033bSKonstantin Ananyev    for (cl = p->busy; cl; cl = cl->next) {
384e18a033bSKonstantin Ananyev        ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
385e18a033bSKonstantin Ananyev                       "pipe buf busy s:%d t:%d f:%d "
386e18a033bSKonstantin Ananyev                       "%p, pos %p, size: %z "
387e18a033bSKonstantin Ananyev                       "file: %O, size: %O",
388e18a033bSKonstantin Ananyev                       (cl->buf->shadow ? 1 : 0),
389e18a033bSKonstantin Ananyev                       cl->buf->temporary, cl->buf->in_file,
390e18a033bSKonstantin Ananyev                       cl->buf->start, cl->buf->pos,
391e18a033bSKonstantin Ananyev                       cl->buf->last - cl->buf->pos,
392e18a033bSKonstantin Ananyev                       cl->buf->file_pos,
393e18a033bSKonstantin Ananyev                       cl->buf->file_last - cl->buf->file_pos);
394e18a033bSKonstantin Ananyev    }
395e18a033bSKonstantin Ananyev
396e18a033bSKonstantin Ananyev    for (cl = p->out; cl; cl = cl->next) {
397e18a033bSKonstantin Ananyev        ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
398e18a033bSKonstantin Ananyev                       "pipe buf out  s:%d t:%d f:%d "
399e18a033bSKonstantin Ananyev                       "%p, pos %p, size: %z "
400e18a033bSKonstantin Ananyev                       "file: %O, size: %O",
401e18a033bSKonstantin Ananyev                       (cl->buf->shadow ? 1 : 0),
402e18a033bSKonstantin Ananyev                       cl->buf->temporary, cl->buf->in_file,
403e18a033bSKonstantin Ananyev                       cl->buf->start, cl->buf->pos,
404e18a033bSKonstantin Ananyev                       cl->buf->last - cl->buf->pos,
405e18a033bSKonstantin Ananyev                       cl->buf->file_pos,
406e18a033bSKonstantin Ananyev                       cl->buf->file_last - cl->buf->file_pos);
407e18a033bSKonstantin Ananyev    }
408e18a033bSKonstantin Ananyev
409e18a033bSKonstantin Ananyev    for (cl = p->in; cl; cl = cl->next) {
410e18a033bSKonstantin Ananyev        ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
411e18a033bSKonstantin Ananyev                       "pipe buf in   s:%d t:%d f:%d "
412e18a033bSKonstantin Ananyev                       "%p, pos %p, size: %z "
413e18a033bSKonstantin Ananyev                       "file: %O, size: %O",
414e18a033bSKonstantin Ananyev                       (cl->buf->shadow ? 1 : 0),
415e18a033bSKonstantin Ananyev                       cl->buf->temporary, cl->buf->in_file,
416e18a033bSKonstantin Ananyev                       cl->buf->start, cl->buf->pos,
417e18a033bSKonstantin Ananyev                       cl->buf->last - cl->buf->pos,
418e18a033bSKonstantin Ananyev                       cl->buf->file_pos,
419e18a033bSKonstantin Ananyev                       cl->buf->file_last - cl->buf->file_pos);
420