NetBSD-5.0.2/regress/lib/libpthread/once3/once3.c

Compare this file to the similar file:
Show the results in this format:

/*	$NetBSD: once3.c,v 1.2 2005/07/16 23:12:02 nathanw Exp $	*/

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void ofunc(void);
void* threadfunc(void *);
void cleanup(void *);
void handler(int, siginfo_t *, void *);

int
main(int argc, char *argv[])
{
	pthread_t thread;
	struct sigaction act;
	struct itimerval it;
	printf("Test 3 of pthread_once() (test versus cancellation)\n");

	act.sa_sigaction = handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_SIGINFO;
	sigaction(SIGALRM, &act, NULL);

	timerclear(&it.it_value);
	it.it_value.tv_usec = 500000;
	timerclear(&it.it_interval);
	setitimer(ITIMER_REAL, &it, NULL);

	pthread_mutex_lock(&mutex);
	pthread_create(&thread, NULL, threadfunc, NULL);
	pthread_cancel(thread);
	pthread_mutex_unlock(&mutex);
	pthread_join(thread, NULL);

	pthread_once(&once, ofunc);

	/* Cancel timer */
	timerclear(&it.it_value);
	setitimer(ITIMER_REAL, &it, NULL);

	printf("Test succeeded\n");

	return 0;
}

void
cleanup(void *m)
{
	pthread_mutex_t *mu = m;

	pthread_mutex_unlock(mu);
}

void
ofunc(void)
{
	
	pthread_testcancel();
}

void *
threadfunc(void *arg)
{

	pthread_mutex_lock(&mutex);
	pthread_cleanup_push(cleanup, &mutex);
	pthread_once(&once, ofunc);
	pthread_cleanup_pop(1);
	return NULL;
}


void
handler(int sig, siginfo_t *info, void *ctx)
{
	printf("Signal handler was called; main thread deadlocked in "
	    "pthread_once().\n"
	    "Test failed.\n");
	exit(1);
}