MEDIUM: connection: close front idling connection on soft-stop
Implement a safe mechanism to close front idling connection which
prevents the soft-stop to complete. Every h1/h2 front connection is
added in a new per-thread list instance. On shutdown, a new task is
waking up which calls wake mux operation on every connection still
present in the new list.
A new stopping_list attach point has been added in the connection
structure. As this member is only used for frontend connections, it
shared the same union as the session_list reserved for backend
connections.
diff --git a/src/haproxy.c b/src/haproxy.c
index 5d3e735..f149fc5 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2370,11 +2370,31 @@
exit(status);
}
+/* Handler of the task of mux_stopping_data.
+ * Called on soft-stop.
+ */
+struct task *mux_stopping_process(struct task *t, void *ctx, unsigned int state)
+{
+ struct connection *conn, *back;
+
+ list_for_each_entry_safe(conn, back, &mux_stopping_data[tid].list, stopping_list) {
+ if (conn->mux && conn->mux->wake)
+ conn->mux->wake(conn);
+ }
+
+ return t;
+}
+
/* Runs the polling loop */
void run_poll_loop()
{
int next, wake;
+ /* allocates the thread bound mux_stopping_data task */
+ mux_stopping_data[tid].task = task_new(tid_bit);
+ mux_stopping_data[tid].task->process = mux_stopping_process;
+ LIST_INIT(&mux_stopping_data[tid].list);
+
tv_update_date(0,1);
while (1) {
wake_expired_tasks();
@@ -2411,6 +2431,12 @@
int i;
if (stopping) {
+ /* stop muxes before acknowleding stopping */
+ if (!(stopping_thread_mask & tid_bit)) {
+ task_wakeup(mux_stopping_data[tid].task, TASK_WOKEN_OTHER);
+ wake = 1;
+ }
+
if (_HA_ATOMIC_OR_FETCH(&stopping_thread_mask, tid_bit) == tid_bit) {
/* notify all threads that stopping was just set */
for (i = 0; i < global.nbthread; i++)
@@ -2438,6 +2464,8 @@
activity[tid].loops++;
}
+
+ task_destroy(mux_stopping_data[tid].task);
}
static void *run_thread_poll_loop(void *data)