summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
authorDimitri Staessens <[email protected]>2023-03-05 12:17:46 +0100
committerSander Vrijders <[email protected]>2023-03-08 11:40:29 +0100
commitf16b4a1954ab4fbca0ec403f6a04c80375328921 (patch)
tree234c1f8dae1d9b72667c2a937d3eab3b2d1dd681 /src/irmd
parentf38936e62cfcf8f0add97c4bea3b5662f3e07a19 (diff)
downloadouroboros-f16b4a1954ab4fbca0ec403f6a04c80375328921.tar.gz
ouroboros-f16b4a1954ab4fbca0ec403f6a04c80375328921.zip
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 <[email protected]> Signed-off-by: Sander Vrijders <[email protected]>
Diffstat (limited to 'src/irmd')
-rw-r--r--src/irmd/irm_flow.c2
-rw-r--r--src/irmd/irm_flow.h1
-rw-r--r--src/irmd/main.c7
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) {