MCPcopy Create free account
hub / github.com/build2/build2 / sigwait_thread_function

Function sigwait_thread_function

b/b.cxx:279–339  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

277static sigset_t sigwait_mask;
278
279static void*
280sigwait_thread_function (void* d)
281{
282 int sig;
283 if (int e = sigwait (&sigwait_mask, &sig))
284 {
285 cerr << "error: unable to wait for signals: "
286 << system_error (e, generic_category ()) // Sanitize.
287 << endl;
288
289 terminate (false /* trace */);
290 }
291
292 if (sig == SIGUSR1) // Request to shutdown.
293 return nullptr;
294
295 // Block all the threads that attempt to issue any diagnostics.
296 //
297 // Note that the primary goal here is to suppress diagnostics about
298 // abnormally terminated child processes, which could have been terminated
299 // due to a signal sent to the whole process group (see
300 // butl::process::wait() implementation for details on the issue we try to
301 // resolve). The blocked threads will stay as such until the process is
302 // terminated.
303 //
304 // Also note that there is still a possibility that after sigwait() returns,
305 // making the signal non-pending, and before the diagnostics mutex is
306 // locked, some threads may print the diagnostics we try to avoid. If it
307 // ever becomes a problem, we can consider using the Linux and FreeBSD
308 // specific signalfd() in combination with select() and read(), which seems
309 // to provide an ability to make the transition from the pending signal to
310 // the locked diagnostics mutex atomic.
311 //
312 diag_stream_lock dl;
313
314 // Instruct the scheduler to pre-shutdown (stop executing new tasks, etc).
315 //
316 build2::scheduler& s (*static_cast<build2::scheduler*> (d));
317 s.shutdown (false /* wait */);
318
319 // Unblock the signal, so that it can be raised.
320 //
321 sigset_t um;
322 sigemptyset (&um);
323 sigaddset (&um, sig);
324
325 if (int e = pthread_sigmask (SIG_UNBLOCK, &um, nullptr /* oldset */))
326 {
327 cerr << "error: unable to unblock signal " << sig << ": "
328 << system_error (e, generic_category ()) // Sanitize.
329 << endl;
330
331 terminate (false /* trace */);
332 }
333
334 // Call the signal handler.
335 //
336 build2_b_cleanup_handler (sig);

Callers

nothing calls this directly

Calls 2

build2_b_cleanup_handlerFunction · 0.85
terminateFunction · 0.70

Tested by

no test coverage detected