Search code examples
c++multithreadingsynchronizationposix

Is there a data race if pthread_cond_signal is the last call in a thread?


Compiling this with -fsanitize=thread yields a data race report between pthread_cond_signal and pthread_cond_destroy:

#include <stdio.h>
#include <pthread.h>
#include <err.h>

bool done = false;

pthread_mutex_t mutex;
pthread_cond_t cond;

void *func(void *)
{   
    pthread_mutex_lock(&mutex);

    done = true;

    pthread_mutex_unlock(&mutex);

    pthread_cond_signal(&cond);

    return NULL;
}

int main()
{
    pthread_t thread;

    pthread_cond_init(&cond, NULL);
    pthread_mutex_init(&mutex, NULL);

    if (pthread_create(&thread, NULL, func, NULL) != 0)
        err(1, "pthread_create()");

    pthread_mutex_lock(&mutex);

    while (!done)
        pthread_cond_wait(&cond, &mutex);

    pthread_mutex_unlock(&mutex);

    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);

    pthread_join(thread, NULL);

    return 0;
}

The report goes away if I call pthread_mutex_unlock after pthread_cond_signal. But the manual says pthread_cond_signal doesn't need the mutex to be taken. Is it documented anywhere that calling pthread_cond_signal as the last call that references a pthread_cond_t, and destroying it from the thread that does pthread_cond_wait is not legal ?


Solution

  • Is it documented anywhere that calling pthread_cond_signal as the last call that references a pthread_cond_t, and destroying it from the thread that does pthread_cond_wait is not legal ?

    They cannot cover all corner cases in documentation. Yes it is legal to call pthread_cond_signal() after mutex unlocked, it is not legal to destroy it at the same time as pthread_cond_signal() can be called.