netbsd-16m-support-20020203
[openafs.git] / src / util / softsig.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #define _POSIX_PTHREAD_SEMANTICS
11 #include <assert.h>
12 #include <stdio.h>
13 #include <signal.h>
14 #include <pthread.h>
15 #include <unistd.h>
16
17 static pthread_t softsig_tid;
18 static struct {
19   void (*handler) (int);
20   int pending;
21 } softsig_sigs[NSIG];
22
23 static void *
24 softsig_thread (void *arg)
25 {
26   sigset_t ss;
27
28   sigemptyset (&ss);
29   sigaddset (&ss, SIGUSR1);
30
31   while (1) {
32     void (*h) (int);
33     int i, sigw;
34
35     h = NULL;
36
37     for (i = 0; i < NSIG; i++)
38       if (softsig_sigs[i].pending) {
39         softsig_sigs[i].pending = 0;
40         h = softsig_sigs[i].handler;
41         break;
42       }
43
44     if (i == NSIG)
45       assert (0 == sigwait (&ss, &sigw));
46     else if (h)
47       h (i);
48   }
49 }
50
51 void
52 softsig_init ()
53 {
54   sigset_t ss, os;
55
56   sigemptyset (&ss);
57   sigaddset (&ss, SIGUSR1);
58
59   /* Set mask right away, so we don't accidentally SIGUSR1 the
60    * softsig thread and cause an exit (default action).
61    */
62   assert (0 == pthread_sigmask (SIG_BLOCK, &ss, &os));
63   assert (0 == pthread_create (&softsig_tid, NULL, &softsig_thread, NULL));
64   assert (0 == pthread_sigmask (SIG_SETMASK, &os, NULL));
65 }
66
67 static void
68 softsig_handler (int signo)
69 {
70   softsig_sigs[signo].pending = 1;
71   pthread_kill (softsig_tid, SIGUSR1);
72 }
73
74 void
75 softsig_signal (int signo, void (*handler) (int))
76 {
77   softsig_sigs[signo].handler = handler;
78   signal (signo, softsig_handler);
79 }
80
81 #if defined(TEST)
82 static void
83 print_foo (int signo)
84 {
85   printf ("foo, signo = %d, tid = %d\n", signo, pthread_self ());
86 }
87
88 int
89 main ()
90 {
91   softsig_init ();
92   softsig_signal (SIGINT, print_foo);
93   printf ("main is tid %d\n", pthread_self ());
94   while (1)
95     sleep (60);
96 }
97 #endif