diff options
Diffstat (limited to 'src/http/ngx_http_copy_filter_module.c')
-rw-r--r-- | src/http/ngx_http_copy_filter_module.c | 38 |
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; |