xref: /openbsd-src/regress/lib/libpthread/pthread_once/pthread_once.c (revision c17c3fed6533ec01dfb59df5f4acfe3e9b1944c0)
1 /*	$OpenBSD: pthread_once.c,v 1.1 2017/10/16 01:46:09 guenther Exp $ */
2 
3 /*
4  * Scott Cheloha <scottcheloha@gmail.com>, 2017. Public Domain.
5  */
6 
7 #include <pthread.h>
8 #include <unistd.h>
9 
10 #include "test.h"
11 
12 pthread_once_t once_control = PTHREAD_ONCE_INIT;
13 int done = 0;
14 
15 void
init_routine(void)16 init_routine(void)
17 {
18 	static int first = 1;
19 
20 	if (first) {
21 		first = 0;
22 		CHECKr(pthread_cancel(pthread_self()));
23 		pthread_testcancel();
24 	}
25 	done = 1;
26 }
27 
28 void *
thread_main(void * arg)29 thread_main(void *arg)
30 {
31 	pthread_once(&once_control, init_routine);
32 	return NULL;
33 }
34 
35 int
main(int argc,char ** argv)36 main(int argc, char **argv)
37 {
38 	pthread_t tid;
39 
40 	CHECKr(pthread_create(&tid, NULL, thread_main, NULL));
41 	CHECKr(pthread_join(tid, NULL));
42 	ASSERT(!done);
43 	alarm(5);	/* if this rings we are probably deadlocked */
44 	CHECKr(pthread_once(&once_control, init_routine));
45 	alarm(0);
46 	ASSERT(done);
47 	SUCCEED;
48 }