diff options
| author | Valentin Bartenev <vbart@nginx.com> | 2015-02-11 17:52:15 +0300 |
|---|---|---|
| committer | Valentin Bartenev <vbart@nginx.com> | 2015-02-11 17:52:15 +0300 |
| commit | 2b8d6ad805a0132844cfbc1cf1c6988dfe8c9973 (patch) | |
| tree | 0cfe79e6cd5bd968c04ec176383c1fd0efc86757 /src/http | |
| parent | 2b7e167dbb59a6d1152c644080e21782b8b675e3 (diff) | |
| download | nginx-2b8d6ad805a0132844cfbc1cf1c6988dfe8c9973.tar.gz nginx-2b8d6ad805a0132844cfbc1cf1c6988dfe8c9973.tar.bz2 | |
Refactored sendfile() AIO preload.
This reduces layering violation and simplifies the logic of AIO preread, since
it's now triggered by the send chain function itself without falling back to
the copy filter. The context of AIO operation is now stored per file buffer,
which makes it possible to properly handle cases when multiple buffers come
from different locations, each with its own configuration.
Diffstat (limited to '')
| -rw-r--r-- | src/http/ngx_http_copy_filter_module.c | 99 | ||||
| -rw-r--r-- | src/http/ngx_http_request.h | 3 |
2 files changed, 36 insertions, 66 deletions
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c index 3ad27b042..cdd7fceb6 100644 --- a/src/http/ngx_http_copy_filter_module.c +++ b/src/http/ngx_http_copy_filter_module.c @@ -20,6 +20,7 @@ static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, ngx_file_t *file); static void ngx_http_copy_aio_event_handler(ngx_event_t *ev); #if (NGX_HAVE_AIO_SENDFILE) +static ssize_t ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file); static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev); #endif #endif @@ -125,7 +126,9 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->aio_handler = ngx_http_copy_aio_handler; } #if (NGX_HAVE_AIO_SENDFILE) - c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE); + if (clcf->aio == NGX_HTTP_AIO_SENDFILE) { + ctx->aio_preload = ngx_http_copy_aio_sendfile_preload; + } #endif } #endif @@ -139,72 +142,19 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->aio = r->aio; #endif - for ( ;; ) { - rc = ngx_output_chain(ctx, in); - - if (ctx->in == NULL) { - r->buffered &= ~NGX_HTTP_COPY_BUFFERED; - - } else { - r->buffered |= NGX_HTTP_COPY_BUFFERED; - } - - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args); - -#if (NGX_HAVE_FILE_AIO && NGX_HAVE_AIO_SENDFILE) - - if (c->busy_sendfile) { - ssize_t n; - off_t offset; - ngx_file_t *file; - ngx_http_ephemeral_t *e; - - if (r->aio) { - c->busy_sendfile = NULL; - return rc; - } - - file = c->busy_sendfile->file; - offset = c->busy_sendfile->file_pos; - - if (file->aio) { - c->busy_count = (offset == file->aio->last_offset) ? - c->busy_count + 1 : 0; - file->aio->last_offset = offset; - - if (c->busy_count > 2) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "sendfile(%V) returned busy again", - &file->name); - c->aio_sendfile = 0; - } - } - - c->busy_sendfile = NULL; - e = (ngx_http_ephemeral_t *) &r->uri_start; - - n = ngx_file_aio_read(file, &e->aio_preload, 1, offset, r->pool); - - if (n > 0) { - in = NULL; - continue; - } + rc = ngx_output_chain(ctx, in); - rc = n; + if (ctx->in == NULL) { + r->buffered &= ~NGX_HTTP_COPY_BUFFERED; - if (rc == NGX_AGAIN) { - file->aio->data = r; - file->aio->handler = ngx_http_copy_aio_sendfile_event_handler; + } else { + r->buffered |= NGX_HTTP_COPY_BUFFERED; + } - r->main->blocked++; - r->aio = 1; - } - } -#endif + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args); - return rc; - } + return rc; } @@ -244,6 +194,29 @@ ngx_http_copy_aio_event_handler(ngx_event_t *ev) #if (NGX_HAVE_AIO_SENDFILE) +static ssize_t +ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file) +{ + ssize_t n; + static u_char buf[1]; + ngx_event_aio_t *aio; + ngx_http_request_t *r; + + n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL); + + if (n == NGX_AGAIN) { + aio = file->file->aio; + aio->handler = ngx_http_copy_aio_sendfile_event_handler; + + r = aio->data; + r->main->blocked++; + r->aio = 1; + } + + return n; +} + + static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev) { diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index cffab9a69..9be0c6e71 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -574,9 +574,6 @@ struct ngx_http_request_s { typedef struct { ngx_http_posted_request_t terminal_posted_request; -#if (NGX_HAVE_AIO_SENDFILE) - u_char aio_preload; -#endif } ngx_http_ephemeral_t; |
