diff options
author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2022-02-17 18:20:20 +0100 |
---|---|---|
committer | Sander Vrijders <sander@ouroboros.rocks> | 2022-02-18 08:43:13 +0100 |
commit | 926e7d76cd290726fc0bccd00b58efda6f01b727 (patch) | |
tree | a0570902eba0a2785a03cf85003e76fa5b3db808 /src/irmd/main.c | |
parent | 6804b725dcc99437e8dc1330447330b08e3c39b8 (diff) | |
download | ouroboros-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.c | 9 |
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); } |