alpaqa 1.0.0a8
Nonconvex constrained optimization
Loading...
Searching...
No Matches
cancel.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <csignal>
5#include <memory>
6#include <stdexcept>
7
8/**
9 * Attach SIGINT and SIGTERM handlers to stop the given solver.
10 * @tparam solver_to_stop
11 * Reference to atomic pointer variable that will store a pointer to
12 * the solver, should be static, so it can be accessed from the signal
13 * handler without causing lifetime issues.
14 * @param solver
15 * The solver that should be stopped by the handler.
16 * @return A RAII object that detaches the handler when destroyed.
17 */
18template <auto &solver_to_stop>
19[[nodiscard]] auto attach_cancellation(auto &solver) {
20 if constexpr (requires { solver.stop(); }) {
21 auto *old = solver_to_stop.exchange(&solver, std::memory_order_release);
22 if (old) {
23 old->stop();
24 throw std::runtime_error(
25 "alpaqa-driver:attach_cancellation is not reentrant");
26 }
27 struct sigaction action;
28 action.sa_handler = [](int) {
29 if (auto *s = solver_to_stop.load(std::memory_order::acquire))
30 s->stop();
31 };
32 sigemptyset(&action.sa_mask);
33 action.sa_flags = 0;
34 sigaction(SIGINT, &action, nullptr);
35 sigaction(SIGTERM, &action, nullptr);
36 }
37 using solver_to_stop_t = std::remove_reference_t<decltype(solver_to_stop)>;
38 auto detach_solver = [](solver_to_stop_t *p) {
39 struct sigaction action;
40 action.sa_handler = SIG_DFL;
41 sigemptyset(&action.sa_mask);
42 action.sa_flags = 0;
43 sigaction(SIGINT, &action, nullptr);
44 sigaction(SIGTERM, &action, nullptr);
45 p->store(nullptr, std::memory_order_relaxed);
46 };
47 return std::unique_ptr<solver_to_stop_t, decltype(detach_solver)>{
48 &solver_to_stop};
49}
auto attach_cancellation(auto &solver)
Attach SIGINT and SIGTERM handlers to stop the given solver.
Definition: cancel.hpp:19