annotate src/os/unix/ngx_freebsd_sendfile_chain.c @ 34:aab2ea7c0458 NGINX_0_1_17

nginx 0.1.17 *) Change: the ngx_http_rewrite_module was rewritten from the scratch. Now it is possible to redirect, to return the error codes, to check the variables and referrers. The directives can be used inside locations. The redirect directive was canceled. *) Feature: the ngx_http_geo_module. *) Feature: the proxy_set_x_var and fastcgi_set_var directives. *) Bugfix: the location configuration with "=" modifier may be used in another location. *) Bugfix: the correct content type was set only for requests that use small caps letters in extension. *) Bugfix: if the proxy_pass or fastcgi_pass directives were set in the location, and access was denied, and the error was redirected to a static page, then the segmentation fault occurred. *) Bugfix: if in a proxied "Location" header was a relative URL, then a host name and a slash were added to them; bug appeared in 0.1.14. *) Bugfix: the system error message was not logged on Linux.
author Igor Sysoev <http://sysoev.ru>
date Thu, 03 Feb 2005 00:00:00 +0300
parents da8c190bdaba
children 72eb30262aac
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
1
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
2 /*
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
4 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
5
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
6
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
9 #include <ngx_event.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
10
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
11
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
12 /*
28
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
13 * Although FreeBSD sendfile() allows to pass a header and a trailer,
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
14 * it can not send a header with a part of the file in one packet until
28
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
15 * FreeBSD 5.3. Besides, over the fast ethernet connection sendfile()
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
16 * may send the partially filled packets, i.e. the 8 file pages may be sent
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
17 * as the 11 full 1460-bytes packets, then one incomplete 324-bytes packet,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
18 * and then again the 11 full 1460-bytes packets.
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
19 *
28
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
20 * Threfore we use the TCP_NOPUSH option (similar to Linux's TCP_CORK)
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
21 * to postpone the sending - it not only sends a header and the first part of
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
22 * the file in one packet, but also sends the file pages in the full packets.
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
23 *
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
24 * But until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush a pending
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
25 * data that less than MSS so that data may be sent with 5 second delay.
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
26 * So we do not use TCP_NOPUSH on FreeBSD prior to 4.5 although it can be used
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
27 * for non-keepalive HTTP connections.
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
28 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
29
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
30
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
31 #define NGX_HEADERS 8
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
32 #define NGX_TRAILERS 4
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
33
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
34
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
35 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
36 off_t limit)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
37 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
38 int rc;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
39 u_char *prev;
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
40 off_t size, send, prev_send, aligned, sent, fprev;
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
41 size_t header_size, file_size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
42 ngx_uint_t eintr, eagain, complete;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
43 ngx_err_t err;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
44 ngx_buf_t *file;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
45 ngx_array_t header, trailer;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
46 ngx_event_t *wev;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
47 ngx_chain_t *cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
48 struct sf_hdtr hdtr;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
49 struct iovec *iov, headers[NGX_HEADERS], trailers[NGX_TRAILERS];
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
50
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
51 wev = c->write;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
52
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
53 if (!wev->ready) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
54 return in;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
55 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
56
18
6f8b0dc0f8dd nginx 0.1.9
Igor Sysoev <http://sysoev.ru>
parents: 10
diff changeset
57 #if (NGX_HAVE_KQUEUE)
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
58
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
59 if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
60 ngx_log_error(NGX_LOG_INFO, c->log, wev->kq_errno,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
61 "kevent() reported about an closed connection");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
62
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
63 wev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
64 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
65 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
66
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
67 #endif
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
68
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
69 /* the maximum limit size is the maximum size_t value - the page size */
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
70
26
45fe5b98a9de nginx 0.1.13
Igor Sysoev <http://sysoev.ru>
parents: 22
diff changeset
71 if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) {
45fe5b98a9de nginx 0.1.13
Igor Sysoev <http://sysoev.ru>
parents: 22
diff changeset
72 limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
73 }
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
74
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
75 send = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
76 eagain = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
77
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
78 header.elts = headers;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
79 header.size = sizeof(struct iovec);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
80 header.nalloc = NGX_HEADERS;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
81 header.pool = c->pool;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
82
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
83 trailer.elts = trailers;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
84 trailer.size = sizeof(struct iovec);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
85 trailer.nalloc = NGX_TRAILERS;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
86 trailer.pool = c->pool;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
87
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
88 for ( ;; ) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
89 file = NULL;
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
90 file_size = 0;
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
91 header_size = 0;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
92 eintr = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
93 complete = 0;
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
94 prev_send = send;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
95
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
96 header.nelts = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
97 trailer.nelts = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
98
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
99 /* create the header iovec and coalesce the neighbouring bufs */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
100
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
101 prev = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
102 iov = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
103
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
104 for (cl = in;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
105 cl && header.nelts < IOV_MAX && send < limit;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
106 cl = cl->next)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
107 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
108 if (ngx_buf_special(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
109 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
110 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
111
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
112 if (!ngx_buf_in_memory_only(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
113 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
114 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
115
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
116 size = cl->buf->last - cl->buf->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
117
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
118 if (send + size > limit) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
119 size = limit - send;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
120 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
121
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
122 if (prev == cl->buf->pos) {
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
123 iov->iov_len += (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
124
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
125 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
126 if (!(iov = ngx_array_push(&header))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
127 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
128 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
129
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
130 iov->iov_base = (void *) cl->buf->pos;
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
131 iov->iov_len = (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
132 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
133
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
134 prev = cl->buf->pos + (size_t) size;
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
135 header_size += (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
136 send += size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
137 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
138
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
139
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
140 if (cl && cl->buf->in_file && send < limit) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
141 file = cl->buf;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
142
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
143 /* coalesce the neighbouring file bufs */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
144
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
145 do {
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
146 size = cl->buf->file_last - cl->buf->file_pos;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
147
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
148 if (send + size > limit) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
149 size = limit - send;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
150
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
151 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
152 & ~(ngx_pagesize - 1);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
153
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
154 if (aligned <= cl->buf->file_last) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
155 size = aligned - cl->buf->file_pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
156 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
157 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
158
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
159 file_size += (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
160 send += size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
161 fprev = cl->buf->file_pos + size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
162 cl = cl->next;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
163
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
164 } while (cl
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
165 && cl->buf->in_file
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
166 && send < limit
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
167 && file->file->fd == cl->buf->file->fd
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
168 && fprev == cl->buf->file_pos);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
169 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
170
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
171
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
172 if (file) {
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
173
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
174 /* create the tailer iovec and coalesce the neighbouring bufs */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
175
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
176 prev = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
177 iov = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
178
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
179 while (cl && header.nelts < IOV_MAX && send < limit) {
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
180
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
181 if (ngx_buf_special(cl->buf)) {
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
182 cl = cl->next;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
183 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
184 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
185
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
186 if (!ngx_buf_in_memory_only(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
187 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
188 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
189
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
190 size = cl->buf->last - cl->buf->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
191
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
192 if (send + size > limit) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
193 size = limit - send;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
194 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
195
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
196 if (prev == cl->buf->pos) {
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
197 iov->iov_len += (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
198
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
199 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
200 if (!(iov = ngx_array_push(&trailer))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
201 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
202 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
203
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
204 iov->iov_base = (void *) cl->buf->pos;
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
205 iov->iov_len = (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
206 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
207
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
208 prev = cl->buf->pos + (size_t) size;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
209 send += size;
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
210 cl = cl->next;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
211 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
212 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
213
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
214 if (file) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
215
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
216 if (ngx_freebsd_use_tcp_nopush
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
217 && c->tcp_nopush == NGX_TCP_NOPUSH_UNSET)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
218 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
219 if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
220 err = ngx_errno;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
221
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
222 /*
28
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
223 * there is a tiny chance to be interrupted, however,
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
224 * we continue a processing without the TCP_NOPUSH
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
225 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
226
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
227 if (err != NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
228 wev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
229 ngx_connection_error(c, err,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
230 ngx_tcp_nopush_n " failed");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
231 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
232 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
233
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
234 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
235 c->tcp_nopush = NGX_TCP_NOPUSH_SET;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
236
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
237 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
238 "tcp_nopush");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
239 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
240 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
241
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
242 hdtr.headers = (struct iovec *) header.elts;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
243 hdtr.hdr_cnt = header.nelts;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
244 hdtr.trailers = (struct iovec *) trailer.elts;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
245 hdtr.trl_cnt = trailer.nelts;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
246
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
247 /*
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
248 * the "nbytes bug" of the old sendfile() syscall:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
249 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
250 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
251
28
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
252 if (!ngx_freebsd_sendfile_nbytes_bug) {
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
253 header_size = 0;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
254 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
255
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
256 sent = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
257
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
258 rc = sendfile(file->file->fd, c->fd, file->file_pos,
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
259 file_size + header_size, &hdtr, &sent, 0);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
260
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
261 if (rc == -1) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
262 err = ngx_errno;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
263
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
264 if (err == NGX_EAGAIN || err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
265 if (err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
266 eintr = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
267
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
268 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
269 eagain = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
270 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
271
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
272 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
273 "sendfile() sent only %O bytes", sent);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
274
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
275 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
276 wev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
277 ngx_connection_error(c, err, "sendfile() failed");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
278 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
279 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
280 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
281
32
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
282 /*
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
283 * sendfile() in FreeBSD 3.x-4.x may return value >= 0
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
284 * on success, although only 0 is documented
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
285 */
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
286
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
287 if (rc >= 0 && sent == 0) {
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
288
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
289 /*
32
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
290 * if rc is OK and sent equal to zero, then someone
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
291 * has truncated the file, so the offset became beyond
da8c190bdaba nginx 0.1.16
Igor Sysoev <http://sysoev.ru>
parents: 28
diff changeset
292 * the end of the file
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
293 */
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
294
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
295 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
296 "sendfile() reported that \"%s\" was truncated",
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
297 file->file->name.data);
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
298
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
299 return NGX_CHAIN_ERROR;
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
300 }
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
301
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
302 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
10
46833bd150cb nginx 0.1.5
Igor Sysoev <http://sysoev.ru>
parents: 4
diff changeset
303 "sendfile: %d, @%O %O:%uz",
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
304 rc, file->file_pos, sent, file_size + header_size);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
305
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
306 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
307 rc = writev(c->fd, header.elts, header.nelts);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
308
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
309 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
310 "writev: %d of %uz", rc, header_size);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
311
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
312 if (rc == -1) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
313 err = ngx_errno;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
314
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
315 if (err == NGX_EAGAIN || err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
316 if (err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
317 eintr = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
318 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
319
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
320 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
321 "writev() not ready");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
322
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
323 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
324 wev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
325 ngx_connection_error(c, err, "writev() failed");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
326 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
327 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
328 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
329
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
330 sent = rc > 0 ? rc : 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
331 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
332
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
333 if (send - prev_send == sent) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
334 complete = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
335 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
336
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
337 c->sent += sent;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
338
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
339 for (cl = in; cl; cl = cl->next) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
340
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
341 if (ngx_buf_special(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
342 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
343 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
344
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
345 if (sent == 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
346 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
347 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
348
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
349 size = ngx_buf_size(cl->buf);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
350
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
351 if (sent >= size) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
352 sent -= size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
353
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
354 if (ngx_buf_in_memory(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
355 cl->buf->pos = cl->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
356 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
357
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
358 if (cl->buf->in_file) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
359 cl->buf->file_pos = cl->buf->file_last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
360 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
361
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
362 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
363 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
364
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
365 if (ngx_buf_in_memory(cl->buf)) {
22
8b6db3bda591 nginx 0.1.11
Igor Sysoev <http://sysoev.ru>
parents: 18
diff changeset
366 cl->buf->pos += (size_t) sent;
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
367 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
368
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
369 if (cl->buf->in_file) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
370 cl->buf->file_pos += sent;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
371 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
372
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
373 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
374 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
375
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
376 if (eagain) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
377
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
378 /*
28
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
379 * sendfile() may return EAGAIN, even if it has sent a whole file
7ca9bdc82b3f nginx 0.1.14
Igor Sysoev <http://sysoev.ru>
parents: 26
diff changeset
380 * part, it indicates that the successive sendfile() call would
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
381 * return EAGAIN right away and would not send anything.
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
382 * We use it as a hint.
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
383 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
384
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
385 wev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
386 return cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
387 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
388
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
389 if (eintr) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
390 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
391 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
392
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
393 if (!complete) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
394 wev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
395 return cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
396 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
397
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
398 if (send >= limit || cl == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
399 return cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
400 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
401
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
402 in = cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
403 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
404 }