Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
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  {
16  std::lock_guard<std::mutex> g(exit_m_);
17  exit_flag_ = true;
18  }
19  exit_cv_.notify_all();
20 
21  if (polling_thread_.joinable()) {
22  polling_thread_.join();
23  }
24 }
25 
26 void SigHandler::start(const std::function<void()>& on_signal) {
27  if (polling_thread_.get_id() != boost::thread::id()) {
28  throw std::runtime_error("SigHandler can only be started once");
29  }
30 
31  polling_thread_ = boost::thread([on_signal]() {
32  std::unique_lock<std::mutex> l(exit_m_);
33  while (true) {
34  bool got_signal = signal_marker_.exchange(false);
35 
36  if (got_signal) {
37  on_signal();
38  return;
39  }
40 
41  if (exit_cv_.wait_for(l, std::chrono::seconds(1), [] { return exit_flag_; })) {
42  break;
43  }
44  }
45  });
46 }
47 
48 void SigHandler::signal(int sig) { ::signal(sig, signal_handler); }
49 
50 void SigHandler::signal_handler(int sig) {
51  (void)sig;
52  bool v = false;
53  // put true if currently set to false
54  SigHandler::signal_marker_.compare_exchange_strong(v, true);
55 }
SigHandler
Definition: sig_handler.h:13