From f16b4a1954ab4fbca0ec403f6a04c80375328921 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sun, 5 Mar 2023 12:17:46 +0100 Subject: irmd: Fix cleanup of failed flows If a flow allocation failed, the flow was left in a pending state instead of a failed state, which caused the irmd to hang on exit. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/irmd/irm_flow.c | 2 +- src/irmd/irm_flow.h | 1 + src/irmd/main.c | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c index 5bc8dde4..8bdda86b 100644 --- a/src/irmd/irm_flow.c +++ b/src/irmd/irm_flow.c @@ -135,7 +135,7 @@ void irm_flow_destroy(struct irm_flow * f) else f->state = FLOW_NULL; - pthread_cond_signal(&f->state_cond); + pthread_cond_broadcast(&f->state_cond); pthread_cleanup_push(cancel_irm_destroy, f); diff --git a/src/irmd/irm_flow.h b/src/irmd/irm_flow.h index 02c51f62..af613d36 100644 --- a/src/irmd/irm_flow.h +++ b/src/irmd/irm_flow.h @@ -34,6 +34,7 @@ enum flow_state { FLOW_NULL = 0, FLOW_ALLOC_PENDING, + FLOW_ALLOC_REQ_PENDING, FLOW_ALLOCATED, FLOW_DEALLOC_PENDING, FLOW_DESTROY diff --git a/src/irmd/main.c b/src/irmd/main.c index 8daa7401..4277be3d 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -200,8 +200,8 @@ static struct irm_flow * get_irm_flow_n(pid_t n_pid) list_for_each(pos, &irmd.irm_flows) { struct irm_flow * e = list_entry(pos, struct irm_flow, next); - if (e->n_pid == n_pid && - irm_flow_get_state(e) == FLOW_ALLOC_PENDING) + enum flow_state state = irm_flow_get_state(e); + if (e->n_pid == n_pid && state == FLOW_ALLOC_REQ_PENDING) return e; } @@ -1446,6 +1446,7 @@ static int flow_alloc(pid_t pid, if (join) { if (ipcp_flow_join(ipcp->pid, flow_id, pid, hash, IPCP_HASH_LEN(ipcp), qs)) { + irm_flow_set_state(f, FLOW_NULL); /* sanitizer cleans this */ log_info("Flow_join failed."); free(hash); @@ -1454,6 +1455,7 @@ static int flow_alloc(pid_t pid, } else { if (ipcp_flow_alloc(ipcp->pid, flow_id, pid, hash, IPCP_HASH_LEN(ipcp), qs, data, len)) { + irm_flow_set_state(f, FLOW_NULL); /* sanitizer cleans this */ log_info("Flow_allocation failed."); free(hash); @@ -1693,6 +1695,7 @@ static int flow_req_arr(pid_t pid, return -1; } + f->state = FLOW_ALLOC_REQ_PENDING; f->mpl = mpl; if (len != 0) { -- cgit v1.2.3