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
12class SignalSet {
13public:
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
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
39private:
40			sigset_t			fSignals;
41};
42
43
44SignalSet::SignalSet()
45{
46	sigemptyset(&fSignals);
47}
48
49
50SignalSet::SignalSet(int signal)
51{
52	SetTo(signal);
53}
54
55
56SignalSet::SignalSet(const sigset_t& signals)
57	:
58	fSignals(signals)
59{
60}
61
62
63void
64SignalSet::SetTo(const sigset_t& signals)
65{
66	fSignals = signals;
67}
68
69
70void
71SignalSet::SetTo(int signal)
72{
73	sigemptyset(&fSignals);
74	sigaddset(&fSignals, signal);
75}
76
77
78bool
79SignalSet::ContainsSignal(int signal) const
80{
81	return sigismember(&fSignals, signal) != 0;
82}
83
84
85SignalSet&
86SignalSet::AddSignal(int signal)
87{
88	sigaddset(&fSignals, signal);
89	return *this;
90}
91
92
93SignalSet&
94SignalSet::AddSignals(const SignalSet& signals)
95{
96	// NOTE: That is not portable.
97	fSignals |= signals.fSignals;
98	return *this;
99}
100
101
102SignalSet&
103SignalSet::RemoveSignal(int signal)
104{
105	sigdelset(&fSignals, signal);
106	return *this;
107}
108
109
110SignalSet&
111SignalSet::RemoveSignals(const SignalSet& signals)
112{
113	// NOTE: That is not portable.
114	fSignals &= ~signals.fSignals;
115	return *this;
116}
117
118
119status_t
120SignalSet::BlockInCurrentThread(SignalSet* oldMask) const
121{
122	return pthread_sigmask(SIG_BLOCK, &fSignals,
123		oldMask != NULL ? &oldMask->fSignals : NULL);
124}
125
126
127status_t
128SignalSet::UnblockInCurrentThread(SignalSet* oldMask) const
129{
130	return pthread_sigmask(SIG_UNBLOCK, &fSignals,
131		oldMask != NULL ? &oldMask->fSignals : NULL);
132}
133
134
135status_t
136SignalSet::SetCurrentThreadSignalMask(SignalSet* oldMask) const
137{
138	return pthread_sigmask(SIG_SETMASK, &fSignals,
139		oldMask != NULL ? &oldMask->fSignals : NULL);
140}
141
142
143/*static*/ SignalSet
144SignalSet::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