Prevent race condition during thread exit cleanup (#21603)
Stelios Fragkakis committed
Jan 21, 2026 at 21:59 UTC
902c1633e5ee20e2198c71c97a040e81f43dc2e0
1 file changed
+9
-2
src/libnetdata/threads/threads.c
+9
-2
@@ -267,10 +267,17 @@ void nd_thread_join_threads()
267
do {
268
spinlock_lock(&threads_globals.exited.spinlock);
269
nti = threads_globals.exited.list;
270
+ if(nti) {
271
+ // Remove from exited list while holding the lock to prevent race condition
272
+ // where another thread with a direct pointer calls nd_thread_join() and frees
273
+ // the nti before we get a chance to use it
274
+ DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(threads_globals.exited.list, nti, prev, next);
275
+ nti->list = ND_THREAD_LIST_NONE;
276
+ }
277
spinlock_unlock(&threads_globals.exited.spinlock);
278
272
- // nd_thread_join() handles NULL and will remove from list and free atomically
273
- // to avoid race with other callers joining the same thread
279
+ // nd_thread_join() handles NULL and will skip list removal since we already did it
280
+ // The atomic CAS in nd_thread_join() still protects against direct callers racing with us
281
nd_thread_join(nti);
282
283
} while (nti);