Mercurial > hg > nginx-vendor-current
comparison src/os/unix/ngx_freebsd_sendfile_chain.c @ 520:d41628eb4d0a NGINX_0_8_12
nginx 0.8.12
*) Feature: the "sendfile" parameter in the "aio" directive on FreeBSD.
*) Bugfix: in try_files; the bug had appeared in 0.8.11.
*) Bugfix: in memcached; the bug had appeared in 0.8.11.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 31 Aug 2009 00:00:00 +0400 |
parents | f7cd062ee035 |
children | 80f7156c2965 |
comparison
equal
deleted
inserted
replaced
519:1fd1b769cd78 | 520:d41628eb4d0a |
---|---|
38 | 38 |
39 | 39 |
40 ngx_chain_t * | 40 ngx_chain_t * |
41 ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) | 41 ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) |
42 { | 42 { |
43 int rc; | 43 int rc, flags; |
44 u_char *prev; | 44 u_char *prev; |
45 off_t size, send, prev_send, aligned, sent, fprev; | 45 off_t size, send, prev_send, aligned, sent, fprev; |
46 size_t header_size, file_size; | 46 size_t header_size, file_size; |
47 ngx_uint_t eintr, eagain, complete; | 47 ngx_uint_t eintr, eagain, complete; |
48 ngx_err_t err; | 48 ngx_err_t err; |
76 limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize; | 76 limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize; |
77 } | 77 } |
78 | 78 |
79 send = 0; | 79 send = 0; |
80 eagain = 0; | 80 eagain = 0; |
81 flags = 0; | |
81 | 82 |
82 header.elts = headers; | 83 header.elts = headers; |
83 header.size = sizeof(struct iovec); | 84 header.size = sizeof(struct iovec); |
84 header.nalloc = NGX_HEADERS; | 85 header.nalloc = NGX_HEADERS; |
85 header.pool = c->pool; | 86 header.pool = c->pool; |
259 header_size = 0; | 260 header_size = 0; |
260 } | 261 } |
261 | 262 |
262 sent = 0; | 263 sent = 0; |
263 | 264 |
265 #if (NGX_HAVE_AIO_SENDFILE) | |
266 flags = c->aio_sendfile ? SF_NODISKIO : 0; | |
267 #endif | |
268 | |
264 rc = sendfile(file->file->fd, c->fd, file->file_pos, | 269 rc = sendfile(file->file->fd, c->fd, file->file_pos, |
265 file_size + header_size, &hdtr, &sent, 0); | 270 file_size + header_size, &hdtr, &sent, flags); |
266 | 271 |
267 if (rc == -1) { | 272 if (rc == -1) { |
268 err = ngx_errno; | 273 err = ngx_errno; |
269 | 274 |
270 if (err == NGX_EAGAIN || err == NGX_EINTR) { | 275 switch (err) { |
271 if (err == NGX_EINTR) { | 276 case NGX_EAGAIN: |
272 eintr = 1; | 277 eagain = 1; |
273 | 278 break; |
274 } else { | 279 |
275 eagain = 1; | 280 case NGX_EINTR: |
276 } | 281 eintr = 1; |
277 | 282 break; |
278 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, | 283 |
279 "sendfile() sent only %O bytes", sent); | 284 #if (NGX_HAVE_AIO_SENDFILE) |
280 | 285 case NGX_EBUSY: |
281 } else { | 286 c->busy_sendfile = file; |
287 break; | |
288 #endif | |
289 | |
290 default: | |
282 wev->error = 1; | 291 wev->error = 1; |
283 (void) ngx_connection_error(c, err, "sendfile() failed"); | 292 (void) ngx_connection_error(c, err, "sendfile() failed"); |
284 return NGX_CHAIN_ERROR; | 293 return NGX_CHAIN_ERROR; |
285 } | 294 } |
295 | |
296 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, | |
297 "sendfile() sent only %O bytes", sent); | |
286 } | 298 } |
287 | 299 |
288 /* | 300 /* |
289 * sendfile() in FreeBSD 3.x-4.x may return value >= 0 | 301 * sendfile() in FreeBSD 3.x-4.x may return value >= 0 |
290 * on success, although only 0 is documented | 302 * on success, although only 0 is documented |
316 "writev: %d of %uz", rc, header_size); | 328 "writev: %d of %uz", rc, header_size); |
317 | 329 |
318 if (rc == -1) { | 330 if (rc == -1) { |
319 err = ngx_errno; | 331 err = ngx_errno; |
320 | 332 |
321 if (err == NGX_EAGAIN || err == NGX_EINTR) { | 333 switch (err) { |
322 if (err == NGX_EINTR) { | 334 case NGX_EAGAIN: |
323 eintr = 1; | 335 break; |
324 } | 336 |
325 | 337 case NGX_EINTR: |
326 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | 338 eintr = 1; |
327 "writev() not ready"); | 339 break; |
328 | 340 |
329 } else { | 341 default: |
330 wev->error = 1; | 342 wev->error = 1; |
331 ngx_connection_error(c, err, "writev() failed"); | 343 ngx_connection_error(c, err, "writev() failed"); |
332 return NGX_CHAIN_ERROR; | 344 return NGX_CHAIN_ERROR; |
333 } | 345 } |
346 | |
347 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
348 "writev() not ready"); | |
334 } | 349 } |
335 | 350 |
336 sent = rc > 0 ? rc : 0; | 351 sent = rc > 0 ? rc : 0; |
337 } | 352 } |
338 | 353 |
376 cl->buf->file_pos += sent; | 391 cl->buf->file_pos += sent; |
377 } | 392 } |
378 | 393 |
379 break; | 394 break; |
380 } | 395 } |
396 | |
397 #if (NGX_HAVE_AIO_SENDFILE) | |
398 if (c->busy_sendfile) { | |
399 return cl; | |
400 } | |
401 #endif | |
381 | 402 |
382 if (eagain) { | 403 if (eagain) { |
383 | 404 |
384 /* | 405 /* |
385 * sendfile() may return EAGAIN, even if it has sent a whole file | 406 * sendfile() may return EAGAIN, even if it has sent a whole file |