xref: /openbsd-src/regress/lib/libpthread/pthread_kill/pthread_kill.c (revision c0166d30bef580b49479621c2c58799b0cd4edde)
1*c0166d30Sguenther /* $OpenBSD: pthread_kill.c,v 1.5 2016/05/10 04:04:34 guenther Exp $ */
2780f8468Smarc /* PUBLIC DOMAIN Oct 2002 <marc@snafu.org> */
3780f8468Smarc 
4780f8468Smarc /*
5780f8468Smarc  * Verify that pthread_kill does the right thing, i.e. the signal
6780f8468Smarc  * is delivered to the correct thread and proper signal processing
7780f8468Smarc  * is performed.
8780f8468Smarc  */
9780f8468Smarc 
10780f8468Smarc #include <signal.h>
11780f8468Smarc #include <stdio.h>
12780f8468Smarc #include <unistd.h>
13db3296cfSderaadt #include <stdlib.h>
14780f8468Smarc 
15780f8468Smarc #include "test.h"
16780f8468Smarc 
17db3296cfSderaadt static void
act_handler(int signal,siginfo_t * siginfo,void * context)18780f8468Smarc act_handler(int signal, siginfo_t *siginfo, void *context)
19780f8468Smarc {
20780f8468Smarc 	struct sigaction sa;
21*c0166d30Sguenther 	char buf[200];
22780f8468Smarc 
23780f8468Smarc 	CHECKe(sigaction(SIGUSR1, NULL, &sa));
24780f8468Smarc 	ASSERT(sa.sa_handler == SIG_DFL);
25780f8468Smarc 	ASSERT(siginfo != NULL);
26*c0166d30Sguenther 	snprintf(buf, sizeof buf,
27*c0166d30Sguenther 	    "act_handler: signal %d, siginfo %p, context %p\n",
28780f8468Smarc 	    signal, siginfo, context);
29*c0166d30Sguenther 	write(STDOUT_FILENO, buf, strlen(buf));
30780f8468Smarc }
31780f8468Smarc 
32db3296cfSderaadt static void *
thread(void * arg)33780f8468Smarc thread(void * arg)
34780f8468Smarc {
35780f8468Smarc 	sigset_t run_mask;
36780f8468Smarc 	sigset_t suspender_mask;
37780f8468Smarc 
38780f8468Smarc 	/* wait for sigusr1 */
39780f8468Smarc 	SET_NAME(arg);
40780f8468Smarc 
41780f8468Smarc 	/* Run with all signals blocked, then suspend for SIGUSR1 */
42780f8468Smarc 	sigfillset(&run_mask);
43780f8468Smarc 	CHECKe(sigprocmask(SIG_SETMASK, &run_mask, NULL));
44780f8468Smarc 	sigfillset(&suspender_mask);
45780f8468Smarc 	sigdelset(&suspender_mask, SIGUSR1);
46780f8468Smarc 	for (;;) {
47780f8468Smarc 		sigsuspend(&suspender_mask);
48780f8468Smarc 		ASSERT(errno == EINTR);
49780f8468Smarc 		printf("Thread %s woke up\n", (char*) arg);
50780f8468Smarc 	}
51780f8468Smarc 
52780f8468Smarc }
53780f8468Smarc 
54780f8468Smarc int
main(int argc,char ** argv)55780f8468Smarc main(int argc, char **argv)
56780f8468Smarc {
57780f8468Smarc 	pthread_t thread1;
58780f8468Smarc 	pthread_t thread2;
59780f8468Smarc 	struct sigaction act;
60780f8468Smarc 
61780f8468Smarc 	act.sa_sigaction = act_handler;
62780f8468Smarc 	sigemptyset(&act.sa_mask);
63780f8468Smarc 	act.sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER;
64780f8468Smarc 	CHECKe(sigaction(SIGUSR1, &act, NULL));
65780f8468Smarc 	CHECKr(pthread_create(&thread1, NULL, thread, "T1"));
66780f8468Smarc 	CHECKr(pthread_create(&thread2, NULL, thread, "T2"));
67780f8468Smarc 	sleep(1);
68780f8468Smarc 
69780f8468Smarc 	/* Signal handler should run once, both threads should awaken */
70780f8468Smarc 	CHECKe(kill(getpid(), SIGUSR1));
71780f8468Smarc 	sleep(1);
72780f8468Smarc 
73780f8468Smarc 	/* Signal handler run once, only T1 should awaken */
74780f8468Smarc 	CHECKe(sigaction(SIGUSR1, &act, NULL));
75780f8468Smarc 	CHECKr(pthread_kill(thread1, SIGUSR1));
76780f8468Smarc 	sleep(1);
77780f8468Smarc 
78780f8468Smarc 	/* Signal handler run once, only T2 should awaken */
79780f8468Smarc 	CHECKe(sigaction(SIGUSR1, &act, NULL));
80780f8468Smarc 	CHECKr(pthread_kill(thread2, SIGUSR1));
81780f8468Smarc 	sleep(1);
82780f8468Smarc 
83780f8468Smarc 	SUCCEED;
84780f8468Smarc }
85