Mercurial > hg > nginx
comparison src/http/ngx_http_copy_filter_module.c @ 6423:c5f81dcf97a7
Copy filter: fixed sendfile aio handlers to set ctx->aio.
Sendfile handlers (aio preload and thread handler) are called within
ctx->output_filter() in ngx_output_chain(), and hence ctx->aio cannot
be set directly in ngx_output_chain(). Meanwhile, it must be set to
make sure loop within ngx_output_chain() will be properly terminated.
There are no known cases that trigger the problem, though in theory
something like aio + sub filter (something that needs body in memory,
and can also free some memory buffers) + sendfile can result in
"task already active" and "second aio post" alerts.
The fix is to set ctx->aio in ngx_http_copy_aio_sendfile_preload()
and ngx_http_copy_thread_handler().
For consistency, ctx->aio is no longer set explicitly in
ngx_output_chain_copy_buf(), as it's now done in
ngx_http_copy_thread_handler().
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 03 Mar 2016 21:14:19 +0300 |
parents | 0256738454dc |
children | ce37362a7a70 |
comparison
equal
deleted
inserted
replaced
6422:768e287a6f36 | 6423:c5f81dcf97a7 |
---|---|
202 #if (NGX_HAVE_AIO_SENDFILE) | 202 #if (NGX_HAVE_AIO_SENDFILE) |
203 | 203 |
204 static ssize_t | 204 static ssize_t |
205 ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file) | 205 ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file) |
206 { | 206 { |
207 ssize_t n; | 207 ssize_t n; |
208 static u_char buf[1]; | 208 static u_char buf[1]; |
209 ngx_event_aio_t *aio; | 209 ngx_event_aio_t *aio; |
210 ngx_http_request_t *r; | 210 ngx_http_request_t *r; |
211 ngx_output_chain_ctx_t *ctx; | |
211 | 212 |
212 n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL); | 213 n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL); |
213 | 214 |
214 if (n == NGX_AGAIN) { | 215 if (n == NGX_AGAIN) { |
215 aio = file->file->aio; | 216 aio = file->file->aio; |
216 aio->handler = ngx_http_copy_aio_sendfile_event_handler; | 217 aio->handler = ngx_http_copy_aio_sendfile_event_handler; |
217 | 218 |
218 r = aio->data; | 219 r = aio->data; |
219 r->main->blocked++; | 220 r->main->blocked++; |
220 r->aio = 1; | 221 r->aio = 1; |
222 | |
223 ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); | |
224 ctx->aio = 1; | |
221 } | 225 } |
222 | 226 |
223 return n; | 227 return n; |
224 } | 228 } |
225 | 229 |
250 ngx_http_copy_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) | 254 ngx_http_copy_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) |
251 { | 255 { |
252 ngx_str_t name; | 256 ngx_str_t name; |
253 ngx_thread_pool_t *tp; | 257 ngx_thread_pool_t *tp; |
254 ngx_http_request_t *r; | 258 ngx_http_request_t *r; |
259 ngx_output_chain_ctx_t *ctx; | |
255 ngx_http_core_loc_conf_t *clcf; | 260 ngx_http_core_loc_conf_t *clcf; |
256 | 261 |
257 r = file->thread_ctx; | 262 r = file->thread_ctx; |
258 | 263 |
259 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 264 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
283 } | 288 } |
284 | 289 |
285 r->main->blocked++; | 290 r->main->blocked++; |
286 r->aio = 1; | 291 r->aio = 1; |
287 | 292 |
293 ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); | |
294 ctx->aio = 1; | |
295 | |
288 return NGX_OK; | 296 return NGX_OK; |
289 } | 297 } |
290 | 298 |
291 | 299 |
292 static void | 300 static void |