Improved signal-thread support for the pthread fileserver,
[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) = NULL;
33     int i, sigw;
34
35     for (i = 0; i < NSIG; i++)
36       if (softsig_sigs[i].pending) {
37         softsig_sigs[i].pending = 0;
38         h = softsig_sigs[i].handler;
39         break;
40       }
41
42     if (i == NSIG)
43       assert (0 == sigwait (&ss, &sigw));
44     else if (h)
45       h (i);
46   }
47 }
48
49 void
50 softsig_init ()
51 {
52   sigset_t ss, os;
53
54   sigemptyset (&ss);
55   sigaddset (&ss, SIGUSR1);
56
57   /* Set mask right away, so we don't accidentally SIGUSR1 the
58    * softsig thread and cause an exit (default action).
59    */
60   assert (0 == pthread_sigmask (SIG_BLOCK, &ss, &os));
61   assert (0 == pthread_create (&softsig_tid, NULL, &softsig_thread, NULL));
62   assert (0 == pthread_sigmask (SIG_SETMASK, &os, NULL));
63 }
64
65 static void
66 softsig_handler (int signo)
67 {
68   softsig_sigs[signo].pending = 1;
69   pthread_kill (softsig_tid, SIGUSR1);
70 }
71
72 void
73 softsig_signal (int signo, void (*handler) (int))
74 {
75   softsig_sigs[signo].handler = handler;
76   signal (signo, softsig_handler);
77 }
78
79 #if defined(TEST)
80 static void
81 print_foo (int signo)
82 {
83   printf ("foo, signo = %d, tid = %d\n", signo, pthread_self ());
84 }
85
86 int
87 main ()
88 {
89   softsig_init ();
90   softsig_signal (SIGINT, print_foo);
91   printf ("main is tid %d\n", pthread_self ());
92   while (1)
93     sleep (60);
94 }
95 #endif