alpaqa 1.0.0a11
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
8namespace alpaqa {
9
10namespace detail {
11inline std::atomic<void *> solver_to_stop;
12}
13
14/**
15 * Attach SIGINT and SIGTERM handlers to stop the given solver.
16 * @param solver
17 * The solver that should be stopped by the handler.
18 * @return A RAII object that detaches the handler when destroyed.
19 */
20template <class Solver>
21[[nodiscard]] auto attach_cancellation(Solver &solver) {
23 using solver_to_stop_t = decltype(solver_to_stop);
24 if constexpr (requires { solver.stop(); }) {
25 auto *old = solver_to_stop.exchange(&solver, std::memory_order_release);
26 if (old) {
27 throw std::logic_error(
28 "alpaqa-driver:attach_cancellation can only be used once");
29 }
30 struct sigaction action;
31 action.sa_handler = [](int) {
32 if (auto *s = solver_to_stop.load(std::memory_order::acquire))
33 reinterpret_cast<Solver *>(s)->stop();
34 };
35 sigemptyset(&action.sa_mask);
36 action.sa_flags = 0;
37 sigaction(SIGINT, &action, nullptr);
38 sigaction(SIGTERM, &action, nullptr);
39 auto detach_solver = +[](solver_to_stop_t *p) {
40 struct sigaction action;
41 action.sa_handler = SIG_DFL;
42 sigemptyset(&action.sa_mask);
43 action.sa_flags = 0;
44 sigaction(SIGINT, &action, nullptr);
45 sigaction(SIGTERM, &action, nullptr);
46 p->store(nullptr, std::memory_order_relaxed);
47 };
48 return std::unique_ptr<solver_to_stop_t, decltype(detach_solver)>{
49 &solver_to_stop, detach_solver};
50 } else {
51 struct [[maybe_unused]] empty {};
52 return empty{};
53 }
54}
55
56} // namespace alpaqa
std::atomic< void * > solver_to_stop
Definition: cancel.hpp:11
auto attach_cancellation(Solver &solver)
Attach SIGINT and SIGTERM handlers to stop the given solver.
Definition: cancel.hpp:21