summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/http/ngx_http_copy_filter_module.c38
-rw-r--r--src/http/ngx_http_upstream.c22
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c13
-rw-r--r--src/os/unix/ngx_linux_sendfile_chain.c9
4 files changed, 58 insertions, 24 deletions
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index c8ad5daee..6c93a3bd9 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -219,13 +219,25 @@ ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file)
ngx_http_request_t *r;
ngx_output_chain_ctx_t *ctx;
+ aio = file->file->aio;
+ r = aio->data;
+
+ if (r->aio) {
+ /*
+ * tolerate sendfile() calls if another operation is already
+ * running; this can happen due to subrequests, multiple calls
+ * of the next body filter from a filter, or in HTTP/2 due to
+ * a write event on the main connection
+ */
+
+ return NGX_AGAIN;
+ }
+
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;
@@ -263,6 +275,7 @@ static ngx_int_t
ngx_http_copy_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
{
ngx_str_t name;
+ ngx_connection_t *c;
ngx_thread_pool_t *tp;
ngx_http_request_t *r;
ngx_output_chain_ctx_t *ctx;
@@ -270,6 +283,27 @@ ngx_http_copy_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
r = file->thread_ctx;
+ if (r->aio) {
+ /*
+ * tolerate sendfile() calls if another operation is already
+ * running; this can happen due to subrequests, multiple calls
+ * of the next body filter from a filter, or in HTTP/2 due to
+ * a write event on the main connection
+ */
+
+ c = r->connection;
+
+#if (NGX_HTTP_V2)
+ if (r->stream) {
+ c = r->stream->connection->connection;
+ }
+#endif
+
+ if (task == c->sendfile_task) {
+ return NGX_OK;
+ }
+ }
+
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
tp = clcf->thread_pool;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 002b3e65d..e22849342 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -3847,6 +3847,7 @@ ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
{
ngx_str_t name;
ngx_event_pipe_t *p;
+ ngx_connection_t *c;
ngx_thread_pool_t *tp;
ngx_http_request_t *r;
ngx_http_core_loc_conf_t *clcf;
@@ -3854,6 +3855,27 @@ ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
r = file->thread_ctx;
p = r->upstream->pipe;
+ if (r->aio) {
+ /*
+ * tolerate sendfile() calls if another operation is already
+ * running; this can happen due to subrequests, multiple calls
+ * of the next body filter from a filter, or in HTTP/2 due to
+ * a write event on the main connection
+ */
+
+ c = r->connection;
+
+#if (NGX_HTTP_V2)
+ if (r->stream) {
+ c = r->stream->connection->connection;
+ }
+#endif
+
+ if (task == c->sendfile_task) {
+ return NGX_OK;
+ }
+ }
+
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
tp = clcf->thread_pool;
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index 3d415bd2c..750c12fc3 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -255,19 +255,6 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
#if (NGX_HAVE_AIO_SENDFILE)
if (ebusy) {
- if (aio->event.active) {
- /*
- * tolerate duplicate calls; they can happen due to subrequests
- * or multiple calls of the next body filter from a filter
- */
-
- if (sent) {
- c->busy_count = 0;
- }
-
- return in;
- }
-
if (sent == 0) {
c->busy_count++;
diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c
index 91e7f1d93..101d91a9a 100644
--- a/src/os/unix/ngx_linux_sendfile_chain.c
+++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -379,15 +379,6 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size)
return ctx->sent;
}
- if (task->event.active && ctx->file == file) {
- /*
- * tolerate duplicate calls; they can happen due to subrequests
- * or multiple calls of the next body filter from a filter
- */
-
- return NGX_DONE;
- }
-
ctx->file = file;
ctx->socket = c->fd;
ctx->size = size;