From 0f9f0ca522fe2413d3bfb79f38c84eeaf84a17a4 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Tue, 5 Sep 2017 15:56:35 -0700 Subject: Fixing racing condition on app port release/request. Application free ports is a queue (double linked list) protected with mutex. After successfull request parsing, each router thread (1) tries to get port from this list. If this list is empty, (2) start worker request posted to main router thread. Another thread may release port between (1) and (2). This fix adds an attempt to get port from free ports list at the beginning of start worker action in main thread. --- src/nxt_router.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/nxt_router.c b/src/nxt_router.c index f557ebaf..65ef7298 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -2146,13 +2146,33 @@ nxt_router_send_sw_request(nxt_task_t *task, void *obj, void *data) uint32_t stream; nxt_buf_t *b; nxt_app_t *app; - nxt_port_t *main_port, *router_port; + nxt_port_t *main_port, *router_port, *app_port; nxt_runtime_t *rt; nxt_start_worker_t *sw; + nxt_req_app_link_t *ra; sw = obj; app = sw->app; + if (nxt_queue_is_empty(&app->requests)) { + ra = sw->ra; + app_port = nxt_router_app_get_port(app, ra->req_id); + + if (app_port != NULL) { + nxt_debug(task, "app '%V' %p process request #%uxD", + &app->name, app, ra->req_id); + + ra->app_port = app_port; + + nxt_router_process_http_request_mp(task, ra, app_port); + + nxt_router_ra_release(task, ra, ra->work.data); + nxt_router_sw_release(task, sw); + + return; + } + } + nxt_queue_insert_tail(&app->requests, &sw->ra->link); if (app->workers + app->pending_workers >= app->max_workers) { -- cgit