pthread_cond_timedwait ignores cancellation request
c, macos, posix, pthreads
Solution
Your expectations about how the code should behave are correct, and in fact it works as expected on other systems I just tested. I think you've just found (yet another) bug in OSX.
Problem
I've got a strange problem with pthread_cond_timedwait(): according to the POSIX specification it is a cancellation point. However, when I'm calling pthread_cancel() on the thread, it never gets cancelled! Instead, pthread_cond_timedwait() continues to run normally. It doesn't lock or anything, it just keeps running as if pthread_cancel() had never been called. As soon as I insert a pthread_testcancel() call, however, the thread gets cancelled correctly! Without the call to pthread_testcancel(), the thread is never cancelled although I'm calling pthread_cond_timedwait() all the time. Does anybody have an idea what's going wrong here? Thanks a lot! EDIT: Here comes the code: ``` #include <stdio.h> #include <pthread.h> #include <time.h> #include <sys/time.h> // replacement function because OS X doesn't seem to have clock_gettime() static int clock_gettime(int clk_id, struct timespec* t) { struct timeval now; int rv = gettimeofday(&now, NULL); if(rv) return rv; t->tv_sec = now.tv_sec; t->tv_nsec = now.tv_usec * 1000; return 0; } static void *threadproc(void *data) { pthread_mutex_t mutex; pthread_mutexattr_t attr; pthread_cond_t cond; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex, &attr); pthread_mutexattr_destroy(&attr); pthread_cond_init(&cond, NULL); for(;;) { struct timespec ts; clock_gettime(0, &ts); // wait 60ms ts.tv_nsec += 60 * 1000000; pthread_mutex_lock(&mutex); pthread_cond_timedwait(&cond, &mutex, &ts); pthread_mutex_unlock(&mutex); #if 0 pthread_testcancel(); #endif } return NULL; } int main(int argc, char *argv[]) { pthread_t pThread; pthread_create(&pThread, NULL, threadproc, NULL); printf("Waiting...\n"); sleep(5); printf("Killing thread...\n"); pthread_cancel(pThread); pthread_join(pThread, NULL); printf("Ok!\n"); return 0; } ```