Race condition with free_io() / wait_cond() and alloc_io() /
cond_signal(), results in lost-wakeups between IO threads
and causes threads and eventually filed to deadlock.
Thread 1 Thread 2
free_io x -
- alloc_io x
- cond_signal x
lock_cond x -
wait_cond x -
Move free_io() inside the mutex locked section before
sleeping, and lock the mutex in wake_iothread before
signalling the thread, to avoid the deadlock.
static struct io* wake_up_next_iothread(struct store *store)
{
struct io *io = alloc_io(store);
+
if (io){
+ pthread_mutex_lock(&io->lock);
pthread_cond_signal(&io->cond);
+ pthread_mutex_unlock(&io->lock);
}
return io;
}
handle_accepted(store, io);
}
else {
- free_io(store, io);
pthread_mutex_lock(&io->lock);
+ free_io(store, io);
pthread_cond_wait(&io->cond, &io->lock);
pthread_mutex_unlock(&io->lock);
}