INSTINCT Code Coverage Report


Directory: src/
File: internal/Sleep.cpp
Date: 2025-06-02 15:19:59
Exec Total Coverage
Lines: 9 41 22.0%
Functions: 1 4 25.0%
Branches: 4 34 11.8%

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