1 /*
2 * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef SIGNAL_SET_H
6 #define SIGNAL_SET_H
7
8
9 #include <signal.h>
10
11
12 class SignalSet {
13 public:
14 SignalSet();
15 SignalSet(int signal);
16 SignalSet(const sigset_t& signals);
17
18 void SetTo(const sigset_t& signals);
19 void SetTo(int signal);
20
Signals()21 const sigset_t& Signals() const { return fSignals; }
22
23 bool ContainsSignal(int signal) const;
24
25 SignalSet& AddSignal(int signal);
26 SignalSet& AddSignals(const SignalSet& signals);
27 SignalSet& RemoveSignal(int signal);
28 SignalSet& RemoveSignals(const SignalSet& signals);
29
30 status_t BlockInCurrentThread(
31 SignalSet* oldMask = NULL) const;
32 status_t UnblockInCurrentThread(
33 SignalSet* oldMask = NULL) const;
34 status_t SetCurrentThreadSignalMask(
35 SignalSet* oldMask = NULL) const;
36
37 static SignalSet CurrentThreadSignalMask();
38
39 private:
40 sigset_t fSignals;
41 };
42
43
SignalSet()44 SignalSet::SignalSet()
45 {
46 sigemptyset(&fSignals);
47 }
48
49
SignalSet(int signal)50 SignalSet::SignalSet(int signal)
51 {
52 SetTo(signal);
53 }
54
55
SignalSet(const sigset_t & signals)56 SignalSet::SignalSet(const sigset_t& signals)
57 :
58 fSignals(signals)
59 {
60 }
61
62
63 void
SetTo(const sigset_t & signals)64 SignalSet::SetTo(const sigset_t& signals)
65 {
66 fSignals = signals;
67 }
68
69
70 void
SetTo(int signal)71 SignalSet::SetTo(int signal)
72 {
73 sigemptyset(&fSignals);
74 sigaddset(&fSignals, signal);
75 }
76
77
78 bool
ContainsSignal(int signal)79 SignalSet::ContainsSignal(int signal) const
80 {
81 return sigismember(&fSignals, signal) != 0;
82 }
83
84
85 SignalSet&
AddSignal(int signal)86 SignalSet::AddSignal(int signal)
87 {
88 sigaddset(&fSignals, signal);
89 return *this;
90 }
91
92
93 SignalSet&
AddSignals(const SignalSet & signals)94 SignalSet::AddSignals(const SignalSet& signals)
95 {
96 // NOTE: That is not portable.
97 fSignals |= signals.fSignals;
98 return *this;
99 }
100
101
102 SignalSet&
RemoveSignal(int signal)103 SignalSet::RemoveSignal(int signal)
104 {
105 sigdelset(&fSignals, signal);
106 return *this;
107 }
108
109
110 SignalSet&
RemoveSignals(const SignalSet & signals)111 SignalSet::RemoveSignals(const SignalSet& signals)
112 {
113 // NOTE: That is not portable.
114 fSignals &= ~signals.fSignals;
115 return *this;
116 }
117
118
119 status_t
BlockInCurrentThread(SignalSet * oldMask)120 SignalSet::BlockInCurrentThread(SignalSet* oldMask) const
121 {
122 return pthread_sigmask(SIG_BLOCK, &fSignals,
123 oldMask != NULL ? &oldMask->fSignals : NULL);
124 }
125
126
127 status_t
UnblockInCurrentThread(SignalSet * oldMask)128 SignalSet::UnblockInCurrentThread(SignalSet* oldMask) const
129 {
130 return pthread_sigmask(SIG_UNBLOCK, &fSignals,
131 oldMask != NULL ? &oldMask->fSignals : NULL);
132 }
133
134
135 status_t
SetCurrentThreadSignalMask(SignalSet * oldMask)136 SignalSet::SetCurrentThreadSignalMask(SignalSet* oldMask) const
137 {
138 return pthread_sigmask(SIG_SETMASK, &fSignals,
139 oldMask != NULL ? &oldMask->fSignals : NULL);
140 }
141
142
143 /*static*/ SignalSet
CurrentThreadSignalMask()144 SignalSet::CurrentThreadSignalMask()
145 {
146 SignalSet signals;
147 pthread_sigmask(SIG_BLOCK, NULL, &signals.fSignals);
148 return signals;
149 }
150
151
152 #endif // SIGNAL_SET_H
153