18template <auto &solver_to_stop>
20 if constexpr (
requires { solver.stop(); }) {
21 auto *old = solver_to_stop.exchange(&solver, std::memory_order_release);
24 throw std::runtime_error(
25 "alpaqa-driver:attach_cancellation is not reentrant");
27 struct sigaction action;
28 action.sa_handler = [](int) {
29 if (
auto *s = solver_to_stop.load(std::memory_order::acquire))
32 sigemptyset(&action.sa_mask);
34 sigaction(SIGINT, &action,
nullptr);
35 sigaction(SIGTERM, &action,
nullptr);
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);
43 sigaction(SIGINT, &action,
nullptr);
44 sigaction(SIGTERM, &action,
nullptr);
45 p->store(
nullptr, std::memory_order_relaxed);
47 return std::unique_ptr<solver_to_stop_t,
decltype(detach_solver)>{
auto attach_cancellation(auto &solver)
Attach SIGINT and SIGTERM handlers to stop the given solver.