comparison src/os/unix/ngx_freebsd_sendfile_chain.c @ 22:8b6db3bda591 NGINX_0_1_11

nginx 0.1.11 *) Feature: the worker_priority directive. *) Change: both tcp_nopush and tcp_nodelay directives affect the transferred response. *) Bugfix: nginx did not call initgroups(). Thanks to Andrew Sitnikov and Andrei Nigmatulin. *) Change: now the ngx_http_autoindex_module shows the file size in the bytes. *) Bugfix: the ngx_http_autoindex_module returned the 500 error if the broken symlink was in a directory. *) Bugfix: the files bigger than 4G could not be transferred using sendfile. *) Bugfix: if the backend was resolved to several backends and there was an error while the response waiting then process may got caught in an endless loop. *) Bugfix: the worker process may exit with the "unknown cycle" message when the /dev/poll method was used. *) Bugfix: "close() channel failed" errors. *) Bugfix: the autodetection of the "nobody" and "nogroup" groups. *) Bugfix: the send_lowat directive did not work on Linux. *) Bugfix: the segmentation fault occurred if there was no events section in configuration. *) Bugfix: nginx could not be built on OpenBSD. *) Bugfix: the double slashes in "://" in the URI were converted to ":/".
author Igor Sysoev <http://sysoev.ru>
date Thu, 02 Dec 2004 00:00:00 +0300
parents 6f8b0dc0f8dd
children 45fe5b98a9de
comparison
equal deleted inserted replaced
21:4eeb9cfef970 22:8b6db3bda591
35 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, 35 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
36 off_t limit) 36 off_t limit)
37 { 37 {
38 int rc; 38 int rc;
39 u_char *prev; 39 u_char *prev;
40 off_t fprev, sent, send, sprev, aligned; 40 off_t size, send, prev_send, aligned, sent, fprev;
41 size_t hsize, fsize; 41 size_t header_size, file_size;
42 ssize_t size;
43 ngx_uint_t eintr, eagain, complete; 42 ngx_uint_t eintr, eagain, complete;
44 ngx_err_t err; 43 ngx_err_t err;
45 ngx_buf_t *file; 44 ngx_buf_t *file;
46 ngx_array_t header, trailer; 45 ngx_array_t header, trailer;
47 ngx_event_t *wev; 46 ngx_event_t *wev;
65 return NGX_CHAIN_ERROR; 64 return NGX_CHAIN_ERROR;
66 } 65 }
67 66
68 #endif 67 #endif
69 68
69 /* the maximum limit size is the maximum size_t value - the page size */
70
71 if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
72 limit = MAX_SIZE_T_VALUE - ngx_pagesize;
73 }
74
70 send = 0; 75 send = 0;
71 eagain = 0; 76 eagain = 0;
72 77
73 header.elts = headers; 78 header.elts = headers;
74 header.size = sizeof(struct iovec); 79 header.size = sizeof(struct iovec);
80 trailer.nalloc = NGX_TRAILERS; 85 trailer.nalloc = NGX_TRAILERS;
81 trailer.pool = c->pool; 86 trailer.pool = c->pool;
82 87
83 for ( ;; ) { 88 for ( ;; ) {
84 file = NULL; 89 file = NULL;
85 fsize = 0; 90 file_size = 0;
86 hsize = 0; 91 header_size = 0;
87 eintr = 0; 92 eintr = 0;
88 complete = 0; 93 complete = 0;
89 sprev = send; 94 prev_send = send;
90 95
91 header.nelts = 0; 96 header.nelts = 0;
92 trailer.nelts = 0; 97 trailer.nelts = 0;
93 98
94 /* create the header iovec and coalesce the neighbouring bufs */ 99 /* create the header iovec and coalesce the neighbouring bufs */
113 if (send + size > limit) { 118 if (send + size > limit) {
114 size = limit - send; 119 size = limit - send;
115 } 120 }
116 121
117 if (prev == cl->buf->pos) { 122 if (prev == cl->buf->pos) {
118 iov->iov_len += size; 123 iov->iov_len += (size_t) size;
119 124
120 } else { 125 } else {
121 if (!(iov = ngx_array_push(&header))) { 126 if (!(iov = ngx_array_push(&header))) {
122 return NGX_CHAIN_ERROR; 127 return NGX_CHAIN_ERROR;
123 } 128 }
124 129
125 iov->iov_base = (void *) cl->buf->pos; 130 iov->iov_base = (void *) cl->buf->pos;
126 iov->iov_len = size; 131 iov->iov_len = (size_t) size;
127 } 132 }
128 133
129 prev = cl->buf->pos + size; 134 prev = cl->buf->pos + (size_t) size;
130 hsize += size; 135 header_size += (size_t) size;
131 send += size; 136 send += size;
132 } 137 }
133 138
134 139
135 if (cl && cl->buf->in_file && send < limit) { 140 if (cl && cl->buf->in_file && send < limit) {
136 file = cl->buf; 141 file = cl->buf;
137 142
138 /* coalesce the neighbouring file bufs */ 143 /* coalesce the neighbouring file bufs */
139 144
140 do { 145 do {
141 size = (size_t) (cl->buf->file_last - cl->buf->file_pos); 146 size = cl->buf->file_last - cl->buf->file_pos;
142 147
143 if (send + size > limit) { 148 if (send + size > limit) {
144 size = limit - send; 149 size = limit - send;
145 150
146 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) 151 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
149 if (aligned <= cl->buf->file_last) { 154 if (aligned <= cl->buf->file_last) {
150 size = aligned - cl->buf->file_pos; 155 size = aligned - cl->buf->file_pos;
151 } 156 }
152 } 157 }
153 158
154 fsize += size; 159 file_size += (size_t) size;
155 send += size; 160 send += size;
156 fprev = cl->buf->file_pos + size; 161 fprev = cl->buf->file_pos + size;
157 cl = cl->next; 162 cl = cl->next;
158 163
159 } while (cl 164 } while (cl
187 if (send + size > limit) { 192 if (send + size > limit) {
188 size = limit - send; 193 size = limit - send;
189 } 194 }
190 195
191 if (prev == cl->buf->pos) { 196 if (prev == cl->buf->pos) {
192 iov->iov_len += size; 197 iov->iov_len += (size_t) size;
193 198
194 } else { 199 } else {
195 if (!(iov = ngx_array_push(&trailer))) { 200 if (!(iov = ngx_array_push(&trailer))) {
196 return NGX_CHAIN_ERROR; 201 return NGX_CHAIN_ERROR;
197 } 202 }
198 203
199 iov->iov_base = (void *) cl->buf->pos; 204 iov->iov_base = (void *) cl->buf->pos;
200 iov->iov_len = size; 205 iov->iov_len = (size_t) size;
201 } 206 }
202 207
203 prev = cl->buf->pos + size; 208 prev = cl->buf->pos + (size_t) size;
204 send += size; 209 send += size;
205 cl = cl->next; 210 cl = cl->next;
206 } 211 }
207 } 212 }
208 213
243 * the "nbytes bug" of the old sendfile() syscall: 248 * the "nbytes bug" of the old sendfile() syscall:
244 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 249 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771
245 */ 250 */
246 251
247 if (ngx_freebsd_sendfile_nbytes_bug == 0) { 252 if (ngx_freebsd_sendfile_nbytes_bug == 0) {
248 hsize = 0; 253 header_size = 0;
249 } 254 }
250 255
251 sent = 0; 256 sent = 0;
252 257
253 rc = sendfile(file->file->fd, c->fd, file->file_pos, 258 rc = sendfile(file->file->fd, c->fd, file->file_pos,
254 fsize + hsize, &hdtr, &sent, 0); 259 file_size + header_size, &hdtr, &sent, 0);
255 260
256 if (rc == -1) { 261 if (rc == -1) {
257 err = ngx_errno; 262 err = ngx_errno;
258 263
259 if (err == NGX_EAGAIN || err == NGX_EINTR) { 264 if (err == NGX_EAGAIN || err == NGX_EINTR) {
263 } else { 268 } else {
264 eagain = 1; 269 eagain = 1;
265 } 270 }
266 271
267 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, 272 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
268 "sendfile() sent only %O bytes", 273 "sendfile() sent only %O bytes", sent);
269 sent);
270 274
271 } else { 275 } else {
272 wev->error = 1; 276 wev->error = 1;
273 ngx_connection_error(c, err, "sendfile() failed"); 277 ngx_connection_error(c, err, "sendfile() failed");
274 return NGX_CHAIN_ERROR; 278 return NGX_CHAIN_ERROR;
289 return NGX_CHAIN_ERROR; 293 return NGX_CHAIN_ERROR;
290 } 294 }
291 295
292 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, 296 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
293 "sendfile: %d, @%O %O:%uz", 297 "sendfile: %d, @%O %O:%uz",
294 rc, file->file_pos, sent, fsize + hsize); 298 rc, file->file_pos, sent, file_size + header_size);
295 299
296 } else { 300 } else {
297 rc = writev(c->fd, header.elts, header.nelts); 301 rc = writev(c->fd, header.elts, header.nelts);
298 302
299 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 303 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
300 "writev: %d of %uz", rc, hsize); 304 "writev: %d of %uz", rc, header_size);
301 305
302 if (rc == -1) { 306 if (rc == -1) {
303 err = ngx_errno; 307 err = ngx_errno;
304 308
305 if (err == NGX_EAGAIN || err == NGX_EINTR) { 309 if (err == NGX_EAGAIN || err == NGX_EINTR) {
318 } 322 }
319 323
320 sent = rc > 0 ? rc : 0; 324 sent = rc > 0 ? rc : 0;
321 } 325 }
322 326
323 if (send - sprev == sent) { 327 if (send - prev_send == sent) {
324 complete = 1; 328 complete = 1;
325 } 329 }
326 330
327 c->sent += sent; 331 c->sent += sent;
328 332
351 355
352 continue; 356 continue;
353 } 357 }
354 358
355 if (ngx_buf_in_memory(cl->buf)) { 359 if (ngx_buf_in_memory(cl->buf)) {
356 cl->buf->pos += sent; 360 cl->buf->pos += (size_t) sent;
357 } 361 }
358 362
359 if (cl->buf->in_file) { 363 if (cl->buf->in_file) {
360 cl->buf->file_pos += sent; 364 cl->buf->file_pos += sent;
361 } 365 }