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.
This commit is contained in:
Willy Tarreau 2012-03-01 23:34:37 +01:00
parent 431946e961
commit 2d5cd479bc

View File

@ -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;