xref: /openbsd-src/regress/lib/libpthread/pthread_atfork/pthread_atfork.c (revision 52dd0f17537155d98cd11ad118a07526d47c8c92)
1*52dd0f17Sfgsch /*	$OpenBSD: pthread_atfork.c,v 1.3 2005/11/05 04:28:46 fgsch Exp $	*/
2c8063e44Sfgsch 
3c8063e44Sfgsch /*
4c8063e44Sfgsch  * Federico Schwindt <fgsch@openbsd.org>, 2005. Public Domain.
5c8063e44Sfgsch  */
6c8063e44Sfgsch 
7c8063e44Sfgsch #include <sys/types.h>
8c8063e44Sfgsch #include <pthread.h>
9c8063e44Sfgsch #include <unistd.h>
10c8063e44Sfgsch 
11c8063e44Sfgsch #include "test.h"
12c8063e44Sfgsch 
13c8063e44Sfgsch int cnt;
14c8063e44Sfgsch 
15c8063e44Sfgsch void
prepare1(void)16c8063e44Sfgsch prepare1(void)
17c8063e44Sfgsch {
18c8063e44Sfgsch 	ASSERT(cnt == 1);
19c8063e44Sfgsch 	cnt--;
20c8063e44Sfgsch }
21c8063e44Sfgsch 
22c8063e44Sfgsch void
prepare2(void)23c8063e44Sfgsch prepare2(void)
24c8063e44Sfgsch {
25c8063e44Sfgsch 	ASSERT(cnt == 2);
26c8063e44Sfgsch 	cnt--;
27c8063e44Sfgsch }
28c8063e44Sfgsch 
29c8063e44Sfgsch void
parent1(void)30c8063e44Sfgsch parent1(void)
31c8063e44Sfgsch {
32c8063e44Sfgsch 	ASSERT(cnt == 0);
33c8063e44Sfgsch 	cnt += 2;
34c8063e44Sfgsch }
35c8063e44Sfgsch 
36c8063e44Sfgsch void
parent2(void)37c8063e44Sfgsch parent2(void)
38c8063e44Sfgsch {
39c8063e44Sfgsch 	ASSERT(cnt == 2);
40c8063e44Sfgsch 	cnt -= 2;
41c8063e44Sfgsch }
42c8063e44Sfgsch 
43c8063e44Sfgsch void
child1(void)44c8063e44Sfgsch child1(void)
45c8063e44Sfgsch {
46c8063e44Sfgsch 	ASSERT(cnt == 0);
47c8063e44Sfgsch 	cnt += 3;
48c8063e44Sfgsch }
49c8063e44Sfgsch 
50c8063e44Sfgsch void
child2(void)51c8063e44Sfgsch child2(void)
52c8063e44Sfgsch {
53c8063e44Sfgsch 	ASSERT(cnt == 3);
54c8063e44Sfgsch 	cnt++;
55c8063e44Sfgsch }
56c8063e44Sfgsch 
57c8063e44Sfgsch void *
forker1(void * arg)58c8063e44Sfgsch forker1(void *arg)
59c8063e44Sfgsch {
60c8063e44Sfgsch 	CHECKr(pthread_atfork(prepare1, parent1, child1));
61c8063e44Sfgsch 
62c8063e44Sfgsch 	cnt = 1;
63c8063e44Sfgsch 	switch (fork()) {
64c8063e44Sfgsch 	case -1:
652c790616Sfgsch 		PANIC("fork");
66c8063e44Sfgsch 		break;
67c8063e44Sfgsch 
68c8063e44Sfgsch 	case 0:
69c8063e44Sfgsch 		ASSERT(cnt == 3);
70c8063e44Sfgsch 		_exit(0);
71c8063e44Sfgsch 
72c8063e44Sfgsch 	default:
73c8063e44Sfgsch 		ASSERT(cnt == 2);
74c8063e44Sfgsch 		break;
75c8063e44Sfgsch 	}
76c8063e44Sfgsch 
77c8063e44Sfgsch 	cnt = 1;
78c8063e44Sfgsch 
79c8063e44Sfgsch 	return (NULL);
80c8063e44Sfgsch }
81c8063e44Sfgsch 
82c8063e44Sfgsch void *
forker2(void * arg)83c8063e44Sfgsch forker2(void *arg)
84c8063e44Sfgsch {
85c8063e44Sfgsch 	CHECKr(pthread_atfork(prepare2, parent2, child2));
86c8063e44Sfgsch 
87c8063e44Sfgsch 	cnt = 2;
88c8063e44Sfgsch 	switch (fork()) {
89c8063e44Sfgsch 	case -1:
902c790616Sfgsch 		PANIC("fork");
91c8063e44Sfgsch 		break;
92c8063e44Sfgsch 
93c8063e44Sfgsch 	case 0:
94c8063e44Sfgsch 		ASSERT(cnt == 4);
95c8063e44Sfgsch 		_exit(0);
96c8063e44Sfgsch 
97c8063e44Sfgsch 	default:
98c8063e44Sfgsch 		ASSERT(cnt == 0);
99c8063e44Sfgsch 		break;
100c8063e44Sfgsch 	}
101c8063e44Sfgsch 
102c8063e44Sfgsch 	cnt = 0;
103c8063e44Sfgsch 
104c8063e44Sfgsch 	return (NULL);
105c8063e44Sfgsch }
106c8063e44Sfgsch 
107c8063e44Sfgsch int
main(int argc,char ** argv)108c8063e44Sfgsch main(int argc, char **argv)
109c8063e44Sfgsch {
110c8063e44Sfgsch 	pthread_t tid;
111c8063e44Sfgsch 
112c8063e44Sfgsch 	CHECKr(pthread_create(&tid, NULL, forker1, NULL));
113c8063e44Sfgsch 	CHECKr(pthread_join(tid, NULL));
114c8063e44Sfgsch 	ASSERT(cnt == 1);
115c8063e44Sfgsch 	CHECKr(pthread_create(&tid, NULL, forker2, NULL));
116c8063e44Sfgsch 	CHECKr(pthread_join(tid, NULL));
117c8063e44Sfgsch 	ASSERT(cnt == 0);
118c8063e44Sfgsch 	SUCCEED;
119c8063e44Sfgsch }
120