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