diff options
Diffstat (limited to 'src/components/utils/src/signals_linux.cc')
-rw-r--r-- | src/components/utils/src/signals_linux.cc | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/src/components/utils/src/signals_linux.cc b/src/components/utils/src/signals_linux.cc index 2e598d1b0f..274c254716 100644 --- a/src/components/utils/src/signals_linux.cc +++ b/src/components/utils/src/signals_linux.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2016, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,29 +35,49 @@ #include "utils/signals.h" -namespace utils { +bool utils::UnsibscribeFromTermination() { + // Disable some system signals receiving in thread + // by blocking those signals + // (system signals processes only in the main thread) + // Mustn't block all signals! + // See "Advanced Programming in the UNIX Environment, 3rd Edition" + // (http://poincare.matf.bg.ac.rs/~ivana//courses/ps/sistemi_knjige/pomocno/apue.pdf, + // "12.8. Threads and Signals". + sigset_t signal_set; + sigemptyset(&signal_set); + sigaddset(&signal_set, SIGINT); + sigaddset(&signal_set, SIGTERM); -bool SubscribeToTerminateSignal(sighandler_t func) { + return !pthread_sigmask(SIG_BLOCK, &signal_set, NULL); +} + +namespace { +bool CatchSIGSEGV(sighandler_t handler) { struct sigaction act; - act.sa_handler = func; + + act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; - bool sigint_subscribed = (sigaction(SIGINT, &act, NULL) == 0); - bool sigterm_subscribed = (sigaction(SIGTERM, &act, NULL) == 0); - - return sigint_subscribed && sigterm_subscribed; + return !sigaction(SIGSEGV, &act, NULL); } +} // namespace -bool SubscribeToFaultSignal(sighandler_t func) { - struct sigaction act; - act.sa_handler = func; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESETHAND; // we only want to catch SIGSEGV once to flush logger queue +bool utils::WaitTerminationSignals(sighandler_t sig_handler) { + sigset_t signal_set; + int sig = -1; - bool sigsegv_subscribed = (sigaction(SIGSEGV, &act, NULL) == 0); + sigemptyset(&signal_set); + sigaddset(&signal_set, SIGINT); + sigaddset(&signal_set, SIGTERM); - return sigsegv_subscribed; -} + if (!CatchSIGSEGV(sig_handler)) { + return false; + } -} // namespace utils + if (!sigwait(&signal_set, &sig)) { + sig_handler(sig); + return true; + } + return false; +} |