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 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 44 SignalSet::SignalSet() 45 { 46 sigemptyset(&fSignals); 47 } 48 49 50 SignalSet::SignalSet(int signal) 51 { 52 SetTo(signal); 53 } 54 55 56 SignalSet::SignalSet(const sigset_t& signals) 57 : 58 fSignals(signals) 59 { 60 } 61 62 63 void 64 SignalSet::SetTo(const sigset_t& signals) 65 { 66 fSignals = signals; 67 } 68 69 70 void 71 SignalSet::SetTo(int signal) 72 { 73 sigemptyset(&fSignals); 74 sigaddset(&fSignals, signal); 75 } 76 77 78 bool 79 SignalSet::ContainsSignal(int signal) const 80 { 81 return sigismember(&fSignals, signal) != 0; 82 } 83 84 85 SignalSet& 86 SignalSet::AddSignal(int signal) 87 { 88 sigaddset(&fSignals, signal); 89 return *this; 90 } 91 92 93 SignalSet& 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& 103 SignalSet::RemoveSignal(int signal) 104 { 105 sigdelset(&fSignals, signal); 106 return *this; 107 } 108 109 110 SignalSet& 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 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 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 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 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