@@ -21,6 +21,9 @@ void _SSignal_StackTrace(int signum, siginfo_t *info, void *ucontext);
21
21
// A boolean indicating whether or not we've initialized our signal thread.
22
22
atomic_flag _SSignal_threadInitialized = ATOMIC_FLAG_INIT;
23
23
24
+ // Set to true to stop the signal thread.
25
+ atomic<bool > _SSignal_threadStopFlag (false );
26
+
24
27
// The signals we've received since the last time this was cleared.
25
28
atomic<uint64_t > _SSignal_pendingSignalBitMask (0 );
26
29
@@ -85,7 +88,7 @@ void SInitializeSignals() {
85
88
sigprocmask (SIG_BLOCK, &signals, 0 );
86
89
87
90
// This is the signal action structure we'll use to specify what to listen for.
88
- struct sigaction newAction;
91
+ struct sigaction newAction = { 0 } ;
89
92
90
93
// The old style handler is explicitly null
91
94
newAction.sa_handler = nullptr ;
@@ -109,7 +112,6 @@ void SInitializeSignals() {
109
112
bool threadAlreadyStarted = _SSignal_threadInitialized.test_and_set ();
110
113
if (!threadAlreadyStarted) {
111
114
_SSignal_signalThread = thread (_SSignal_signalHandlerThreadFunc);
112
- _SSignal_signalThread.detach ();
113
115
}
114
116
}
115
117
@@ -124,10 +126,24 @@ void _SSignal_signalHandlerThreadFunc() {
124
126
125
127
// Now we wait for any signal to occur.
126
128
while (true ) {
129
+
127
130
// Wait for a signal to appear.
128
- int signum = 0 ;
129
- int result = sigwait (&signals, &signum);
130
- if (!result) {
131
+ siginfo_t siginfo = {0 };
132
+ struct timespec timeout;
133
+ timeout.tv_sec = 1 ;
134
+ timeout.tv_nsec = 0 ;
135
+ int result = -1 ;
136
+ while (result == -1 ) {
137
+ result = sigtimedwait (&signals, &siginfo, &timeout);
138
+ if (_SSignal_threadStopFlag) {
139
+ // Done.
140
+ SINFO (" Stopping signal handler thread." );
141
+ return ;
142
+ }
143
+ }
144
+ int signum = siginfo.si_signo ;
145
+
146
+ if (result > 0 ) {
131
147
// Do the same handling for these functions here as any other thread.
132
148
if (signum == SIGSEGV || signum == SIGABRT || signum == SIGFPE || signum == SIGILL || signum == SIGBUS) {
133
149
_SSignal_StackTrace (signum, nullptr , nullptr );
@@ -140,6 +156,16 @@ void _SSignal_signalHandlerThreadFunc() {
140
156
}
141
157
}
142
158
159
+ void SStopSignalThread () {
160
+ _SSignal_threadStopFlag = true ;
161
+ if (_SSignal_threadInitialized.test_and_set ()) {
162
+ // Send ourselves a singnal to interrupt our thread.
163
+ SINFO (" Joining signal thread." );
164
+ _SSignal_signalThread.join ();
165
+ _SSignal_threadInitialized.clear ();
166
+ }
167
+ }
168
+
143
169
void _SSignal_StackTrace (int signum, siginfo_t *info, void *ucontext) {
144
170
if (signum == SIGSEGV || signum == SIGABRT || signum == SIGFPE || signum == SIGILL || signum == SIGBUS) {
145
171
// If we haven't already saved a signal number, we'll do it now. Any signal we catch here will generate a
0 commit comments