There is a race condition that can occur under high load where a child is reaped before being added to the waiters list.
/*
* Fork & save the PID for later reaping.
*/
+ pthread_mutex_lock(&thread_pool.wait_mutex);
child_pid = fork();
if (child_pid > 0) {
int rcode;
tf->pid = child_pid;
- pthread_mutex_lock(&thread_pool.wait_mutex);
rcode = fr_hash_table_insert(thread_pool.waiters, tf);
- pthread_mutex_unlock(&thread_pool.wait_mutex);
if (!rcode) {
ERROR("Failed to store PID, creating what will be a zombie process %d",
free(tf);
}
}
+ /*
+ * Do not unlock in child process
+ */
+ if(child_pid != 0 ) {
+ pthread_mutex_unlock(&thread_pool.wait_mutex);
+ }
/*
* Return whatever we were told.