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 12static volatile int c0; 13static volatile int c1; 14static volatile int child; 15 16static void handler0(int sig) 17{ 18 c0++; 19} 20 21static 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 30static 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 56int 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