summaryrefslogtreecommitdiff
path: root/src/irmd/main.c
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2022-02-17 18:20:20 +0100
committerSander Vrijders <sander@ouroboros.rocks>2022-02-18 08:43:13 +0100
commit926e7d76cd290726fc0bccd00b58efda6f01b727 (patch)
treea0570902eba0a2785a03cf85003e76fa5b3db808 /src/irmd/main.c
parent6804b725dcc99437e8dc1330447330b08e3c39b8 (diff)
downloadouroboros-926e7d76cd290726fc0bccd00b58efda6f01b727.tar.gz
ouroboros-926e7d76cd290726fc0bccd00b58efda6f01b727.zip
irmd: Fix race condition in sanitize thread
Unlocking the flows while iterating could cause a modification during the iteration. Added pthread_cleanup handlers as the thread could get cancelled while holding a lock. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/irmd/main.c')
-rw-r--r--src/irmd/main.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 22d94136..a87f191a 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -1872,6 +1872,7 @@ void * irm_sanitize(void * o)
return (void *) 0;
pthread_rwlock_wrlock(&irmd.reg_lock);
+ pthread_cleanup_push(__cleanup_rwlock_unlock, &irmd.reg_lock);
list_for_each_safe(p, h, &irmd.spawned_pids) {
struct pid_el * e = list_entry(p, struct pid_el, next);
@@ -1919,8 +1920,10 @@ void * irm_sanitize(void * o)
}
}
- pthread_rwlock_unlock(&irmd.reg_lock);
+ pthread_cleanup_pop(true);
+
pthread_rwlock_wrlock(&irmd.flows_lock);
+ pthread_cleanup_push(__cleanup_rwlock_unlock, &irmd.flows_lock);
list_for_each_safe(p, h, &irmd.irm_flows) {
int ipcpi;
@@ -1945,9 +1948,7 @@ void * irm_sanitize(void * o)
irm_flow_set_state(f, FLOW_DEALLOC_PENDING);
ipcpi = f->n_1_pid;
flow_id = f->flow_id;
- pthread_rwlock_unlock(&irmd.flows_lock);
ipcp_flow_dealloc(ipcpi, flow_id, DEALLOC_TIME);
- pthread_rwlock_wrlock(&irmd.flows_lock);
continue;
}
@@ -1963,7 +1964,7 @@ void * irm_sanitize(void * o)
}
}
- pthread_rwlock_unlock(&irmd.flows_lock);
+ pthread_cleanup_pop(true);
nanosleep(&timeout, NULL);
}