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
prepare1(void)16 prepare1(void)
17 {
18 ASSERT(cnt == 1);
19 cnt--;
20 }
21
22 void
prepare2(void)23 prepare2(void)
24 {
25 ASSERT(cnt == 2);
26 cnt--;
27 }
28
29 void
parent1(void)30 parent1(void)
31 {
32 ASSERT(cnt == 0);
33 cnt += 2;
34 }
35
36 void
parent2(void)37 parent2(void)
38 {
39 ASSERT(cnt == 2);
40 cnt -= 2;
41 }
42
43 void
child1(void)44 child1(void)
45 {
46 ASSERT(cnt == 0);
47 cnt += 3;
48 }
49
50 void
child2(void)51 child2(void)
52 {
53 ASSERT(cnt == 3);
54 cnt++;
55 }
56
57 void *
forker1(void * arg)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 *
forker2(void * arg)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
main(int argc,char ** argv)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