Kagome
Polkadot Runtime Engine in C++17
app_state_manager_impl.cpp
Go to the documentation of this file.
1 
7 
8 #include <csignal>
9 #include <functional>
10 
11 namespace kagome::application {
12 
13  std::weak_ptr<AppStateManager> AppStateManagerImpl::wp_to_myself;
14 
16  if (auto self = wp_to_myself.lock()) {
17  self->shutdown();
18  }
19  }
20 
22  : logger_(log::createLogger("AppStateManager", "application")) {
23  struct sigaction act {};
24  memset(&act, 0, sizeof(act));
25  act.sa_handler = shuttingDownSignalsHandler; // NOLINT
26  sigset_t set; // NOLINT
27  sigemptyset(&set);
28  sigaddset(&set, SIGINT);
29  sigaddset(&set, SIGTERM);
30  sigaddset(&set, SIGQUIT);
31  act.sa_mask = set;
32  sigaction(SIGINT, &act, nullptr);
33  sigaction(SIGTERM, &act, nullptr);
34  sigaction(SIGQUIT, &act, nullptr);
35  sigprocmask(SIG_UNBLOCK, &act.sa_mask, nullptr);
36  }
37 
39  struct sigaction act {};
40  memset(&act, 0, sizeof(act));
41  act.sa_handler = SIG_DFL; // NOLINT
42  sigset_t set; // NOLINT
43  sigemptyset(&set);
44  sigaddset(&set, SIGINT);
45  sigaddset(&set, SIGTERM);
46  sigaddset(&set, SIGQUIT);
47  act.sa_mask = set;
48  sigaction(SIGINT, &act, nullptr);
49  sigaction(SIGTERM, &act, nullptr);
50  sigaction(SIGQUIT, &act, nullptr);
51  }
52 
54  std::lock_guard lg(mutex_);
55  while (!prepare_.empty()) prepare_.pop();
56  while (!launch_.empty()) launch_.pop();
57  while (!shutdown_.empty()) shutdown_.pop();
59  shutdown_requested_ = false;
60  }
61 
63  std::lock_guard lg(mutex_);
64  if (state_ > State::Init) {
65  throw AppStateException("adding callback for stage 'prepare'");
66  }
67  prepare_.emplace(std::move(cb));
68  }
69 
71  std::lock_guard lg(mutex_);
73  throw AppStateException("adding callback for stage 'launch'");
74  }
75  launch_.emplace(std::move(cb));
76  }
77 
79  std::lock_guard lg(mutex_);
80  if (state_ > State::Works) {
81  throw AppStateException("adding callback for stage 'shutdown'");
82  }
83  shutdown_.emplace(std::move(cb));
84  }
85 
87  std::lock_guard lg(mutex_);
88  if (state_ != State::Init) {
89  throw AppStateException("running stage 'prepare'");
90  }
92 
93  while (!prepare_.empty()) {
94  auto &cb = prepare_.front();
95  if (state_ == State::Prepare) {
96  auto success = cb();
97  if (not success) {
99  }
100  }
101  prepare_.pop();
102  }
103 
104  if (state_ == State::Prepare) {
106  } else {
107  shutdown();
108  }
109  }
110 
112  std::lock_guard lg(mutex_);
113  if (state_ != State::ReadyToStart) {
114  throw AppStateException("running stage 'launch'");
115  }
117 
118  while (!launch_.empty()) {
119  auto &cb = launch_.front();
120  if (state_ == State::Starting) {
121  auto success = cb();
122  if (not success) {
124  }
125  }
126  launch_.pop();
127  }
128 
129  if (state_ == State::Starting) {
131  } else {
132  shutdown();
133  }
134  }
135 
137  std::lock_guard lg(mutex_);
138  if (state_ == State::ReadyToStop) {
139  return;
140  }
141 
142  while (!prepare_.empty()) prepare_.pop();
143 
144  while (!launch_.empty()) launch_.pop();
145 
147 
148  while (!shutdown_.empty()) {
149  auto &cb = shutdown_.front();
150  cb();
151  shutdown_.pop();
152  }
153 
155  }
156 
158  wp_to_myself = weak_from_this();
159  if (wp_to_myself.expired()) {
160  throw std::logic_error(
161  "AppStateManager must be instantiated on shared pointer before run");
162  }
163 
164  doPrepare();
165 
166  if (state_ == State::ReadyToStart) {
167  doLaunch();
168  }
169 
170  std::unique_lock lock(cv_mutex_);
171  cv_.wait(lock, [&] { return shutdown_requested_.load(); });
172 
173  doShutdown();
174  }
175 
177  shutdown_requested_ = true;
178  std::lock_guard lg(cv_mutex_);
179  cv_.notify_one();
180  }
181 } // namespace kagome::application
static std::weak_ptr< AppStateManager > wp_to_myself
void run() override
Start application life cycle.
void atShutdown(OnShutdown &&cb) override
Execute.
void atPrepare(OnPrepare &&cb) override
Execute.
void atLaunch(OnLaunch &&cb) override
Execute.
void shutdown() override
Initiate shutting down (at any time)
Logger createLogger(const std::string &tag)
Definition: logger.cpp:112