Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pthread_cond_timedwait ignores cancellation request

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;
}
like image 445
Andreas Avatar asked Dec 01 '25 14:12

Andreas


1 Answers

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.

like image 72
R.. GitHub STOP HELPING ICE Avatar answered Dec 04 '25 02:12

R.. GitHub STOP HELPING ICE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!