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