Aktualizr
C++ SOTA Client
sig_handler.cc
1 #include "sig_handler.h"
2 #include "logging/logging.h"
3 
4 std::atomic<bool> SigHandler::signal_marker_;
5 std::mutex SigHandler::exit_m_;
6 std::condition_variable SigHandler::exit_cv_;
7 bool SigHandler::exit_flag_;
8 
9 SigHandler& SigHandler::get() {
10  static SigHandler handler;
11  return handler;
12 }
13 
14 SigHandler::~SigHandler() {
15  try {
16  {
17  std::lock_guard<std::mutex> g(exit_m_);
18  exit_flag_ = true;
19  }
20  exit_cv_.notify_all();
21 
22  if (polling_thread_.joinable()) {
23  polling_thread_.join();
24  }
25  } catch (...) {
26  }
27 }
28 
29 void SigHandler::start(const std::function<void()>& on_signal) {
30  if (polling_thread_.get_id() != boost::thread::id()) {
31  throw std::runtime_error("SigHandler can only be started once");
32  }
33 
34  polling_thread_ = boost::thread([on_signal]() {
35  std::unique_lock<std::mutex> l(exit_m_);
36  while (true) {
37  bool got_signal = signal_marker_.exchange(false);
38 
39  if (got_signal) {
40  on_signal();
41  return;
42  }
43 
44  if (exit_cv_.wait_for(l, std::chrono::seconds(1), [] { return exit_flag_; })) {
45  break;
46  }
47  }
48  });
49 }
50 
51 void SigHandler::signal(int sig) { ::signal(sig, signal_handler); }
52 
53 void SigHandler::signal_handler(int sig) {
54  (void)sig;
55  bool v = false;
56  // put true if currently set to false
57  SigHandler::signal_marker_.compare_exchange_strong(v, true);
58 }
SigHandler
Definition: sig_handler.h:13