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