summaryrefslogtreecommitdiffhomepage
path: root/src/http
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2015-02-11 17:52:15 +0300
committerValentin Bartenev <vbart@nginx.com>2015-02-11 17:52:15 +0300
commit2b8d6ad805a0132844cfbc1cf1c6988dfe8c9973 (patch)
tree0cfe79e6cd5bd968c04ec176383c1fd0efc86757 /src/http
parent2b7e167dbb59a6d1152c644080e21782b8b675e3 (diff)
downloadnginx-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.c99
-rw-r--r--src/http/ngx_http_request.h3
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;