Hello misc@,

doing some C programming with threads (yeah *ugh*), I discovered a
        strange issue.

There seems to be some problem using "static mutexes" (a mutex not
created by pthread_mutex_init()).

Here is some test code which works very well on linux, but gives:
------> (ID:2238337024)
First
mutex_prob: thread1: pthread_mutex_unlock() (0): Undefined error: 0

on OpenBSD.

The output should look like:
------> (ID:<somenumber>)
First
Second
Thread <somenumber2> done
Thread <somenumber3> done
<------ (ID:<somenumber>)

the mutex is looked by the main-thread and only thread1 may print
without locking the mutex first, thus "First" will always be printed
first.

If this is not a bug, perhaps somebody can point out the API difference
between OpenBSD and Linux I missed.

Regards
ahb


Test code:
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

/* static mutex var */
static pthread_mutex_t fz_mutex = PTHREAD_MUTEX_INITIALIZER;

static void
thread1(void *name)
{
        printf("First\n");

        /* free Mutex */
        if (pthread_mutex_unlock(&fz_mutex) != 0)
                err(1, "thread1: pthread_mutex_unlock() (%d)", errno);

        /* thread end */
        pthread_exit((void *)pthread_self());
}

static void
thread2(void *name)
{
        /* lock Mutex */
        pthread_mutex_lock(&fz_mutex);

        printf("Second\n");

        /* free Mutex again */
        if (pthread_mutex_unlock(&fz_mutex) != 0)
                err(1, "thread2: pthread_mutex_unlock() (%d)", errno);

        /* thread end */
        pthread_exit((void *)pthread_self());
}

int
main(void)
{
        static pthread_t th1, th2;
        static int ret1, ret2;

        /* main thread */
        printf("\n------> (ID:%lu)\n", pthread_self());

        /* lock mutex */
        pthread_mutex_lock(&fz_mutex);

        /* Threads erzeugen */
        if (pthread_create(&th1, NULL, (void *)&thread1,NULL)
            != 0)
                err(1, "pthread_create(th1)");
        if (pthread_create(&th2, NULL, (void *)&thread2,NULL)
            != 0)
                err(1, "pthread_create(th2)");

        /* Wait for both threads to finish */
        pthread_join(th1, (void *)&ret1);
        pthread_join(th2, (void *)&ret2);

        printf("Thread %lu done\n", th1);
        printf("Thread %lu done\n", th2);
        
        printf("<----- (ID: %lu)\n", pthread_self());

        return EXIT_SUCCESS;
}


Compile:
gcc -o foo foo.c -lpthread

Reply via email to