On Mon, Mar 17, 2008 at 04:33:34PM +0100, Andreas Bihlmaier wrote:
> 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:
Correct test code (on #openbsd oenoene just pointed out to me that errno
does not get set (doh!)):
#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

/* static Mutex-Variable */
static pthread_mutex_t fz_mutex = PTHREAD_MUTEX_INITIALIZER;

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

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

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

static void
thread2(void *name)
{
        int ret;

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

        printf("Second\n");

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

        /* 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;
}

Reply via email to