Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bug in pthread_cond_timedwait



I'm running NetBSD-current at home, and been irritated for some
time by various threaded applications aborting like this:

Error detected by libpthread: Destroying condition variable in use.
Detected by file "/usr/src/lib/libpthread/pthread_cond.c", line 95, function "pthread_cond_destroy".

I finally decided to dig into this and figure out why.
It turns out this is a but in pthread_cond_timedwait(); when it
hits a timeout it doesn't clean up the association from condition
variable to mutex so the condition variable thinks it's in use
when it's really not.

Anyone have a quick fix for this?

Test program given below.

  -  Arne H. J.

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

void waitabit()
{
        int ret;
        pthread_mutex_t m;
        pthread_cond_t c;
        struct timespec tspec;

        memset(&tspec, 0, sizeof(tspec));
        tspec.tv_sec = 0;
        tspec.tv_nsec = 100 * 1000 * 1000; /* 0.1 s */

        ret = pthread_cond_init(&c, NULL);
        if (ret != 0) { perror("pthread_cond_init"); exit(1); }
        ret = pthread_mutex_init(&m, NULL);
        if (ret != 0) { perror("pthread_mutex_init"); exit(1); }

        ret = pthread_mutex_lock(&m);
        if (ret != 0) { perror("pthread_mutex_lock"); exit(1); }

        ret = pthread_cond_timedwait(&c, &m, &tspec);
        if (ret != 0) { perror("pthread_cond_timedwait"); }

        ret = pthread_mutex_unlock(&m);
        if (ret != 0) { perror("pthread_mutex_unlock"); exit(1); }

        ret = pthread_cond_destroy(&c);
        if (ret != 0) { perror("pthread_cond_destroy"); exit(1); }
        ret = pthread_mutex_destroy(&m);
        if (ret != 0) { perror("pthread_mutex_destroy"); exit(1); }
}

void* run(void *arg)
{
        waitabit();
        return NULL;
}

int main()
{
        void *jret;
        int ret;
        pthread_t the_thread;

        ret = pthread_create(&the_thread, NULL, run, NULL);
        if (ret != 0) { perror("pthread_create"); return 1; }

        ret = pthread_join(the_thread, &jret);
        if (ret != 0) { perror("pthread_join"); return 1; }

        return 0;
}



Home | Main Index | Thread Index | Old Index