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 <mutex> | ||
11 | #include <condition_variable> | ||
12 | #include "util/Logger.hpp" | ||
13 | |||
14 | #if !__linux__ && !__APPLE__ && !__CYGWIN__ && !__QNXNTO__ | ||
15 | #include <chrono> | ||
16 | #include <thread> | ||
17 | #else | ||
18 | #include <unistd.h> | ||
19 | #endif | ||
20 | #include <csignal> | ||
21 | |||
22 | namespace | ||
23 | { | ||
24 | /// Flag for interrupt check | ||
25 | bool usr_interrupt = false; | ||
26 | /// Condition variable for waiting | ||
27 | std::condition_variable cv; | ||
28 | /// Mutex for condition variabel and interrupt flag access | ||
29 | std::mutex cv_m; | ||
30 | |||
31 | ✗ | void handler(int signum) | |
32 | { | ||
33 | #if !_WIN32 | ||
34 | ✗ | switch (signum) | |
35 | { | ||
36 | ✗ | case SIGUSR1: | |
37 | ✗ | LOG_DEBUG("SIGUSR1 caught"); | |
38 | ✗ | break; | |
39 | ✗ | case SIGINT: | |
40 | ✗ | LOG_DEBUG("SIGINT caught"); | |
41 | ✗ | break; | |
42 | ✗ | case SIGTERM: | |
43 | ✗ | LOG_DEBUG("SIGTERM caught"); | |
44 | ✗ | break; | |
45 | ✗ | default: | |
46 | ✗ | LOG_DEBUG("Unexpected signal caught: {}", signum); | |
47 | } | ||
48 | #else | ||
49 | LOG_DEBUG("Signal caught"); | ||
50 | #endif | ||
51 | { | ||
52 | ✗ | std::lock_guard lk(cv_m); | |
53 | ✗ | usr_interrupt = true; | |
54 | ✗ | } | |
55 | ✗ | cv.notify_one(); | |
56 | ✗ | } | |
57 | } // namespace | ||
58 | |||
59 | ✗ | void NAV::Sleep::waitForSignal(bool showText) | |
60 | { | ||
61 | LOG_TRACE("called"); | ||
62 | |||
63 | #if !_WIN32 | ||
64 | ✗ | usr_interrupt = false; | |
65 | ✗ | static_cast<void>(signal(SIGUSR1, handler)); | |
66 | ✗ | static_cast<void>(signal(SIGINT, handler)); | |
67 | ✗ | static_cast<void>(signal(SIGTERM, handler)); | |
68 | |||
69 | ✗ | if (showText) | |
70 | { | ||
71 | ✗ | LOG_INFO("Programm waits for one of the signals: -SIGUSR1 / -SIGINT (Ctrl + c) / -SIGTERM"); | |
72 | } | ||
73 | |||
74 | ✗ | std::unique_lock lk(cv_m); | |
75 | ✗ | cv.wait(lk, [] { return usr_interrupt; }); | |
76 | ✗ | LOG_DEBUG("Continuing"); | |
77 | |||
78 | ✗ | static_cast<void>(signal(SIGUSR1, SIG_DFL)); | |
79 | ✗ | static_cast<void>(signal(SIGINT, SIG_DFL)); | |
80 | ✗ | static_cast<void>(signal(SIGTERM, SIG_DFL)); | |
81 | #else | ||
82 | LOG_ERROR("Waiting for Sigterm is not supported in Windows"); | ||
83 | #endif | ||
84 | ✗ | } | |
85 | |||
86 | 1 | void NAV::Sleep::countDownSeconds(size_t seconds) | |
87 | { | ||
88 | LOG_TRACE("called with seconds={}", seconds); | ||
89 | |||
90 | 1 | static_cast<void>(signal(SIGINT, handler)); | |
91 | 1 | static_cast<void>(signal(SIGTERM, handler)); | |
92 | |||
93 |
3/4✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
6 | for (size_t i = 0; i < seconds && !usr_interrupt; i++) |
94 | { | ||
95 |
1/2✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
|
5 | LOG_INFO("{} seconds till program finishes", seconds - i); |
96 | |||
97 | // Use of system sleep better here, as it interrupts on signal | ||
98 | #if __linux__ || __APPLE__ || __CYGWIN__ || __QNXNTO__ | ||
99 | 5 | sleep(1); // NOLINT(concurrency-mt-unsafe) // error: function is not thread safe | |
100 | #else | ||
101 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); | ||
102 | #endif | ||
103 | } | ||
104 | |||
105 | 1 | static_cast<void>(signal(SIGINT, SIG_DFL)); | |
106 | 1 | static_cast<void>(signal(SIGTERM, SIG_DFL)); | |
107 | 1 | } | |
108 |