f5de5416f019c4292ca44546ab9aab68cf4e6e6b
[libc-test] / src / regression / raise-race.c
1 // commit: 370f78f2c80c64b7b0780a01e672494a26b5678e 2011-03-09
2 // raise should be robust against forking from a signal handler
3 #include <pthread.h>
4 #include <signal.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <sys/wait.h>
8 #include <unistd.h>
9 #include "test.h"
10
11 static volatile int c0;
12 static volatile int c1;
13 static volatile int child;
14
15 static void handler0(int sig)
16 {
17         c0++;
18 }
19
20 static void handler1(int sig)
21 {
22         c1++;
23         switch (fork()) {
24         case 0: child=1; break;
25         case -1: t_error("fork failed: %s\n", strerror(errno));
26         }
27 }
28
29 static void *start(void *arg)
30 {
31         int i,r,s;
32
33         for (i = 0; i < 1000; i++) {
34                 r = raise(SIGRTMIN);
35                 if (r)
36                         t_error("raise failed: %s\n", strerror(errno));
37         }
38         if (c0 != 1000)
39                 t_error("lost signals: got %d, wanted 1000 (ischild %d forks %d)\n", c0, child, c1);
40         if (child)
41                 _exit(t_status);
42
43         /* make sure we got all pthread_kills, then wait the forked children */
44         while (c1 < 100);
45         for (i = 0; i < 100; i++) {
46                 r = wait(&s);
47                 if (r == -1)
48                         t_error("wait failed: %s\n", strerror(errno));
49                 else if (!WIFEXITED(s) || WTERMSIG(s))
50                         t_error("child failed: pid:%d status:%d\n", r, s);
51         }
52         return 0;
53 }
54
55 int main(void)
56 {
57         pthread_t t;
58         void *p;
59         int r, i, s;
60
61         if (signal(SIGRTMIN, handler0) == SIG_ERR)
62                 t_error("registering signal handler failed: %s\n", strerror(errno));
63         if (signal(SIGRTMIN+1, handler1) == SIG_ERR)
64                 t_error("registering signal handler failed: %s\n", strerror(errno));
65
66         r = pthread_create(&t, 0, start, 0);
67         if (r)
68                 t_error("pthread_create failed: %s\n", strerror(r));
69         for (i = 0; i < 100; i++) {
70                 r = pthread_kill(t, SIGRTMIN+1);
71                 if (r)
72                         t_error("phread_kill failed: %s\n", strerror(r));
73         }
74         r = pthread_join(t,&p);
75         if (r)
76                 t_error("pthread_join failed: %s\n", strerror(r));
77         return t_status;
78 }