1 /* $OpenBSD: pthread_kill.c,v 1.2 2002/10/23 22:30:04 marc Exp $ */ 2 /* PUBLIC DOMAIN Oct 2002 <marc@snafu.org> */ 3 4 /* 5 * Verify that pthread_kill does the right thing, i.e. the signal 6 * is delivered to the correct thread and proper signal processing 7 * is performed. 8 */ 9 10 #include <signal.h> 11 #include <stdio.h> 12 #include <unistd.h> 13 14 #include "test.h" 15 16 void 17 act_handler(int signal, siginfo_t *siginfo, void *context) 18 { 19 struct sigaction sa; 20 char *str; 21 22 CHECKe(sigaction(SIGUSR1, NULL, &sa)); 23 ASSERT(sa.sa_handler == SIG_DFL); 24 ASSERT(siginfo != NULL); 25 asprintf(&str, "act_handler: signal %d, siginfo %p, context %p\n", 26 signal, siginfo, context); 27 write(STDOUT_FILENO, str, strlen(str)); 28 } 29 30 void * 31 thread(void * arg) 32 { 33 sigset_t run_mask; 34 sigset_t suspender_mask; 35 36 /* wait for sigusr1 */ 37 SET_NAME(arg); 38 39 /* Run with all signals blocked, then suspend for SIGUSR1 */ 40 sigfillset(&run_mask); 41 CHECKe(sigprocmask(SIG_SETMASK, &run_mask, NULL)); 42 sigfillset(&suspender_mask); 43 sigdelset(&suspender_mask, SIGUSR1); 44 for (;;) { 45 sigsuspend(&suspender_mask); 46 ASSERT(errno == EINTR); 47 printf("Thread %s woke up\n", (char*) arg); 48 } 49 50 } 51 52 int 53 main(int argc, char **argv) 54 { 55 pthread_t thread1; 56 pthread_t thread2; 57 struct sigaction act; 58 59 act.sa_sigaction = act_handler; 60 sigemptyset(&act.sa_mask); 61 act.sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER; 62 CHECKe(sigaction(SIGUSR1, &act, NULL)); 63 CHECKr(pthread_create(&thread1, NULL, thread, "T1")); 64 CHECKr(pthread_create(&thread2, NULL, thread, "T2")); 65 sleep(1); 66 67 /* Signal handler should run once, both threads should awaken */ 68 CHECKe(kill(getpid(), SIGUSR1)); 69 sleep(1); 70 71 /* Signal handler run once, only T1 should awaken */ 72 CHECKe(sigaction(SIGUSR1, &act, NULL)); 73 CHECKr(pthread_kill(thread1, SIGUSR1)); 74 sleep(1); 75 76 /* Signal handler run once, only T2 should awaken */ 77 CHECKe(sigaction(SIGUSR1, &act, NULL)); 78 CHECKr(pthread_kill(thread2, SIGUSR1)); 79 sleep(1); 80 81 SUCCEED; 82 } 83