1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
diff --git a/core/src/daemon.c b/core/src/daemon.c
index e3463fc..eae23ec 100644
--- a/core/src/daemon.c
+++ b/core/src/daemon.c
@@ -306,6 +306,35 @@ void handler_alarm(int unused)
return;
}
+int process_switch_sig(int sig)
+{
+ /* Switch from silent to verbose. */
+ if (sig == SIGUSR1) {
+ pthread_mutex_lock(&mtx_paint);
+ pthread_mutex_lock(&mtx_tty);
+ ioctl(fd_tty[config.tty_s], VT_RELDISP, 1);
+ pthread_mutex_unlock(&mtx_tty);
+
+ ctty = CTTY_VERBOSE;
+ pthread_mutex_unlock(&mtx_paint);
+ return 1;
+ /* Switch back to silent. */
+ } else if (sig == SIGUSR2) {
+ pthread_mutex_lock(&mtx_paint);
+ pthread_mutex_lock(&mtx_tty);
+ ioctl(fd_tty[config.tty_s], VT_RELDISP, 2);
+ pthread_mutex_unlock(&mtx_tty);
+
+ ctty = CTTY_SILENT;
+ pthread_mutex_unlock(&mtx_paint);
+
+ switch_silent();
+ return 2;
+ }
+
+ return 0;
+}
+
/*
* Signal handler.
*
@@ -315,7 +344,7 @@ void handler_alarm(int unused)
*/
void* thf_sighandler(void *unusued)
{
- sigset_t sigset;
+ sigset_t sigset, sigset_switch;
int sig;
/* We don't handle SIGALRM. */
@@ -329,31 +358,39 @@ void* thf_sighandler(void *unusued)
sigaddset(&sigset, SIGTERM);
sigaddset(&sigset, SIGINT);
+ sigemptyset(&sigset_switch);
+ sigaddset(&sigset_switch, SIGUSR1);
+ sigaddset(&sigset_switch, SIGUSR2);
+
while (1) {
sigwait(&sigset, &sig);
- /* Switch from silent to verbose. */
- if (sig == SIGUSR1) {
- pthread_mutex_lock(&mtx_paint);
- pthread_mutex_lock(&mtx_tty);
- ioctl(fd_tty[config.tty_s], VT_RELDISP, 1);
- pthread_mutex_unlock(&mtx_tty);
-
- ctty = CTTY_VERBOSE;
- pthread_mutex_unlock(&mtx_paint);
- /* Switch back to silent. */
- } else if (sig == SIGUSR2) {
- pthread_mutex_lock(&mtx_paint);
- pthread_mutex_lock(&mtx_tty);
- ioctl(fd_tty[config.tty_s], VT_RELDISP, 2);
- pthread_mutex_unlock(&mtx_tty);
-
- ctty = CTTY_SILENT;
- pthread_mutex_unlock(&mtx_paint);
+ process_switch_sig(sig);
+
+ /* Internally generated terminate signal */
+ if (sig == SIGINT) {
+ struct timespec timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 0;
+ bool pending = true;
+
+ /*
+ * Process any remaining signals. There are no guarantees as to the
+ * order in which the signals are delivered, so we have to make sure
+ * all pending signals are processed before exiting.
+ */
+ while (pending) {
+ sig = sigtimedwait(&sigset_switch, NULL, &timeout);
+
+ if (sig == -1) {
+ /* No more pending signals. */
+ if (errno == EAGAIN)
+ pending = false;
+ } else {
+ process_switch_sig(sig);
+ }
+ }
- switch_silent();
- } else if (sig == SIGINT) {
- /* internally generated terminate signal */
do_cleanup();
pthread_exit(NULL);
} else if (sig == SIGTERM) {
|