From 2d5cd479bc7a8c1ced70e562956e3ae99fe7eec9 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 1 Mar 2012 23:34:37 +0100 Subject: [PATCH] BUG: queue: fix dequeueing sequence on HTTP keep-alive sessions When a request completes on a server and the server connection is closed while the client connection stays open, the HTTP engine releases all server connection slots and scans the queues to offer the connection slot to another pending request. An issue happens when the released connection allows other requests to be dequeued : may_dequeue_tasks() relies on srv->served which is only decremented by sess_change_server() which itself is only called after may_dequeue_tasks(). This results in no connection being woken up until another connection terminates so that may_dequeue_tasks() is called again. This fix is minimalist and only moves sess_change_server() earlier (which is safe). It should be reworked and the code factored out so that the same occurrence in session.c shares the same code. This bug has been there since the introduction of option-http-server-close and the fix must be backported to 1.4. --- src/proto_http.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/proto_http.c b/src/proto_http.c index 5efc7ec75..f36dc3c73 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -4035,8 +4035,11 @@ void http_end_txn_clean_session(struct session *s) http_silent_debug(__LINE__, s); - if (s->flags & SN_BE_ASSIGNED) + if (s->flags & SN_BE_ASSIGNED) { s->be->beconn--; + if (unlikely(s->srv_conn)) + sess_change_server(s, NULL); + } s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now); session_process_counters(s); @@ -4093,8 +4096,6 @@ void http_end_txn_clean_session(struct session *s) process_srv_queue(target_srv(&s->target)); } - if (unlikely(s->srv_conn)) - sess_change_server(s, NULL); clear_target(&s->target); s->req->cons->state = s->req->cons->prev_state = SI_ST_INI;