summaryrefslogtreecommitdiff
path: root/src/http/ngx_http_copy_filter_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_copy_filter_module.c')
-rw-r--r--src/http/ngx_http_copy_filter_module.c38
1 files changed, 36 insertions, 2 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;