Line |
Branch |
Exec |
Source |
1 |
|
|
// This file is part of INSTINCT, the INS Toolkit for Integrated |
2 |
|
|
// Navigation Concepts and Training by the Institute of Navigation of |
3 |
|
|
// the University of Stuttgart, Germany. |
4 |
|
|
// |
5 |
|
|
// This Source Code Form is subject to the terms of the Mozilla Public |
6 |
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this |
7 |
|
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/. |
8 |
|
|
|
9 |
|
|
#include "Sleep.hpp" |
10 |
|
|
#include "util/Logger.hpp" |
11 |
|
|
|
12 |
|
|
#if !__linux__ && !__APPLE__ && !__CYGWIN__ && !__QNXNTO__ |
13 |
|
|
#include <chrono> |
14 |
|
|
#include <thread> |
15 |
|
|
#else |
16 |
|
|
#include <unistd.h> |
17 |
|
|
#endif |
18 |
|
|
#include <csignal> |
19 |
|
|
|
20 |
|
|
namespace |
21 |
|
|
{ |
22 |
|
|
/// Flag for interrupt check |
23 |
|
|
volatile sig_atomic_t usr_interrupt = 0; |
24 |
|
|
|
25 |
|
✗ |
void handler(int /* */) |
26 |
|
|
{ |
27 |
|
✗ |
LOG_DEBUG("Signal caught"); |
28 |
|
✗ |
usr_interrupt = 1; |
29 |
|
✗ |
} |
30 |
|
|
} // namespace |
31 |
|
|
|
32 |
|
✗ |
void NAV::Sleep::waitForSignal(bool showText) |
33 |
|
|
{ |
34 |
|
|
LOG_TRACE("called"); |
35 |
|
|
|
36 |
|
|
#if !_WIN32 |
37 |
|
✗ |
usr_interrupt = 0; |
38 |
|
|
sigset_t mask; |
39 |
|
|
sigset_t oldmask; |
40 |
|
|
// Set up the mask of signals to temporarily block. |
41 |
|
✗ |
sigemptyset(&mask); |
42 |
|
✗ |
sigaddset(&mask, SIGUSR1); |
43 |
|
✗ |
sigaddset(&mask, SIGINT); |
44 |
|
✗ |
sigaddset(&mask, SIGTERM); |
45 |
|
✗ |
static_cast<void>(signal(SIGUSR1, handler)); |
46 |
|
✗ |
static_cast<void>(signal(SIGINT, handler)); |
47 |
|
✗ |
static_cast<void>(signal(SIGTERM, handler)); |
48 |
|
|
|
49 |
|
✗ |
if (showText) |
50 |
|
|
{ |
51 |
|
✗ |
LOG_INFO("Programm waits for one of the signals: -SIGUSR1 / -SIGINT (Ctrl + c) / -SIGTERM"); |
52 |
|
|
} |
53 |
|
|
|
54 |
|
|
// Wait for a signal to arrive. |
55 |
|
✗ |
sigprocmask(SIG_BLOCK, &mask, &oldmask); // NOLINT(concurrency-mt-unsafe) // error: function is not thread safe |
56 |
|
✗ |
while (!usr_interrupt) |
57 |
|
|
{ |
58 |
|
✗ |
sigsuspend(&oldmask); // NOLINT(concurrency-mt-unsafe) // error: function is not thread safe |
59 |
|
|
} |
60 |
|
✗ |
sigprocmask(SIG_UNBLOCK, &mask, nullptr); // NOLINT(concurrency-mt-unsafe) // error: function is not thread safe |
61 |
|
|
|
62 |
|
✗ |
static_cast<void>(signal(SIGUSR1, SIG_DFL)); |
63 |
|
✗ |
static_cast<void>(signal(SIGINT, SIG_DFL)); |
64 |
|
✗ |
static_cast<void>(signal(SIGTERM, SIG_DFL)); |
65 |
|
|
#else |
66 |
|
|
LOG_ERROR("Waiting for Sigterm is not supported in Windows"); |
67 |
|
|
#endif |
68 |
|
✗ |
} |
69 |
|
|
|
70 |
|
✗ |
void NAV::Sleep::countDownSeconds(size_t seconds) |
71 |
|
|
{ |
72 |
|
|
LOG_TRACE("called with seconds={}", seconds); |
73 |
|
|
|
74 |
|
✗ |
static_cast<void>(signal(SIGINT, handler)); |
75 |
|
✗ |
static_cast<void>(signal(SIGTERM, handler)); |
76 |
|
|
|
77 |
|
✗ |
for (size_t i = 0; i < seconds && !usr_interrupt; i++) |
78 |
|
|
{ |
79 |
|
✗ |
LOG_INFO("{} seconds till program finishes", seconds - i); |
80 |
|
|
|
81 |
|
|
// Use of system sleep better here, as it interrupts on signal |
82 |
|
|
#if __linux__ || __APPLE__ || __CYGWIN__ || __QNXNTO__ |
83 |
|
✗ |
sleep(1); // NOLINT(concurrency-mt-unsafe) // error: function is not thread safe |
84 |
|
|
#else |
85 |
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
86 |
|
|
#endif |
87 |
|
|
} |
88 |
|
|
|
89 |
|
✗ |
static_cast<void>(signal(SIGINT, SIG_DFL)); |
90 |
|
✗ |
static_cast<void>(signal(SIGTERM, SIG_DFL)); |
91 |
|
✗ |
} |
92 |
|
|
|