Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion fpsdk_common/include/fpsdk_common/app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,48 @@ class SigIntHelper
bool WaitAbort(const uint32_t millis = 0);
};

/**
* @brief Helper to catch SIGTERM
*
* On construction this installs a handler for SIGTERM. On destruction it sets the handler back to its previous state.
* Note that signal handlers are global and therefore you can only use one SigTermHelper in a app.
*/
class SigTermHelper
{
public:
/**
* @brief Constructor
*
* @param[in] warn Print a WARNING() (true, default) or a DEBUG() (false) on signal
*/
SigTermHelper(const bool warn = true);

/**
* @brief Destructor
*/
~SigTermHelper();

/**
* @brief Check if signal was raised and we should abort
*
* @returns true if signal was raised and we should abort, false otherwise
*/
bool ShouldAbort();

/**
* @brief Wait (block) until signal is raised and we should abort
*
* @param[in] millis Wait at most this long [ms], 0 = forever
*
* @returns true if the signal was raised, false if timeout expired
*/
bool WaitAbort(const uint32_t millis = 0);
};

/**
* @brief Helper to catch SIGPIPE
*
* On construction this installs a handler for SIGPIE. On destruction it sets the handler back to its previous state.
* On construction this installs a handler for SIGPIPE. On destruction it sets the handler back to its previous state.
* Note that signal handlers are global and therefore you can only use one SigPipeHelper in a app.
*/
class SigPipeHelper
Expand Down
61 changes: 61 additions & 0 deletions fpsdk_common/src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,67 @@ bool SigIntHelper::WaitAbort(const uint32_t millis)

// ---------------------------------------------------------------------------------------------------------------------

static bool g_sigterm_abort = false;
static bool g_sigterm_warn = false;
static sighandler_t g_sigterm_old_handler = SIG_IGN;
static fpsdk::common::thread::BinarySemaphore g_sigterm_sem;

static void SigTermHandler(int signum)
{
if ((signum == SIGTERM) && !g_sigterm_abort) {
if (g_sigterm_warn) {
WARNING("Caught SIGTERM, aborting...");
} else {
DEBUG("Caught SIGTERM, aborting...");
}
g_sigterm_abort = true;

// Handle signal only once, next time let the original handler deal with it
std::signal(SIGTERM, g_sigterm_old_handler == SIG_IGN ? SIG_DFL : g_sigterm_old_handler);
g_sigterm_old_handler = SIG_IGN;

g_sigterm_sem.Notify();
}
}

SigTermHelper::SigTermHelper(const bool warn)
{
if (g_sigterm_old_handler == SIG_IGN) {
g_sigterm_old_handler = std::signal(SIGTERM, SigTermHandler);
g_sigterm_warn = warn;
}
}

SigTermHelper::~SigTermHelper()
{
std::signal(SIGTERM, g_sigterm_old_handler == SIG_IGN ? SIG_DFL : g_sigterm_old_handler);
g_sigterm_sem.Notify();
}

bool SigTermHelper::ShouldAbort()
{
return g_sigterm_abort;
}

bool SigTermHelper::WaitAbort(const uint32_t millis)
{
// Wait with timeout
if (millis > 0) {
return g_sigterm_sem.WaitFor(millis) == thread::WaitRes::WOKEN;
}
// Wait forever
else {
while (true) {
if (g_sigterm_sem.WaitFor(1234) == thread::WaitRes::WOKEN) {
return true;
}
}
}
return false;
}

// ---------------------------------------------------------------------------------------------------------------------

static bool g_sigpipe_raised = false;
static bool g_sigpipe_warn = false;
static sighandler_t g_sigpipe_old_handler = SIG_IGN;
Expand Down
Loading