Is the following code valid?
#include <stdio.h> #include <signal.h> #include <pthread.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void sigint_handler(int sig) { pthread_mutex_unlock(&mutex); return; } int main(void) { signal(SIGINT, sigint_handler); pthread_mutex_lock(&mutex); printf("About to wait\n"); pthread_mutex_lock(&mutex); printf("Ok, done!\n"); }
It certainly works on Linux, but on at least FreeBSD it will not as deadlock detection will kick in when the thread tries to lock the mutex it already has locked. Using signals in threaded code is probably a bad idea but I believe the deadlock detection is broken in this case.
Of course, the right way to do this is to use a condition variable and use a pthread_cond_wait() call in main() and wake it up from the signal handler. This works fine.
Moral of the story -- check the return value of pthread_mutex_lock() because sometimes it may not be what you expect! It's much easier to debug a error message about pthread_mutex_lock returning some strange EDEADLCK code than to try and find why your multithreaded application seems to be randomly crashing on another operating system.