xref: /openbsd-src/regress/lib/libpthread/pthread_kill/pthread_kill.c (revision 47911bd667ac77dc523b8a13ef40b012dbffa741)
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