comparison src/http/ngx_http_upstream.c @ 7974:555533169506

HTTP/2: fixed "task already active" with sendfile in threads. With sendfile in threads, "task already active" alerts might appear in logs if a write event happens on the main HTTP/2 connection, triggering a sendfile in threads while another thread operation is already running. Observed with "aio threads; aio_write on; sendfile on;" and with thread event handlers modified to post a write event to the main HTTP/2 connection (though can happen without any modifications). Similarly, sendfile() with AIO preloading on FreeBSD can trigger duplicate aio operation, resulting in "second aio post" alerts. This is, however, harder to reproduce, especially on modern FreeBSD systems, since sendfile() usually does not return EBUSY. Fix is to avoid starting a sendfile operation if other thread operation is active by checking r->aio in the thread handler (and, similarly, in aio preload handler). The added check also makes duplicate calls protection redundant, so it is removed.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 25 Nov 2021 22:02:05 +0300
parents 862f6130d357
children a7a77549265e
comparison
equal deleted inserted replaced
7973:3443c02ca1d1 7974:555533169506
3845 static ngx_int_t 3845 static ngx_int_t
3846 ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) 3846 ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
3847 { 3847 {
3848 ngx_str_t name; 3848 ngx_str_t name;
3849 ngx_event_pipe_t *p; 3849 ngx_event_pipe_t *p;
3850 ngx_connection_t *c;
3850 ngx_thread_pool_t *tp; 3851 ngx_thread_pool_t *tp;
3851 ngx_http_request_t *r; 3852 ngx_http_request_t *r;
3852 ngx_http_core_loc_conf_t *clcf; 3853 ngx_http_core_loc_conf_t *clcf;
3853 3854
3854 r = file->thread_ctx; 3855 r = file->thread_ctx;
3855 p = r->upstream->pipe; 3856 p = r->upstream->pipe;
3857
3858 if (r->aio) {
3859 /*
3860 * tolerate sendfile() calls if another operation is already
3861 * running; this can happen due to subrequests, multiple calls
3862 * of the next body filter from a filter, or in HTTP/2 due to
3863 * a write event on the main connection
3864 */
3865
3866 c = r->connection;
3867
3868 #if (NGX_HTTP_V2)
3869 if (r->stream) {
3870 c = r->stream->connection->connection;
3871 }
3872 #endif
3873
3874 if (task == c->sendfile_task) {
3875 return NGX_OK;
3876 }
3877 }
3856 3878
3857 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 3879 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
3858 tp = clcf->thread_pool; 3880 tp = clcf->thread_pool;
3859 3881
3860 if (tp == NULL) { 3882 if (tp == NULL) {