RDKit: ControlCHandler.h Source File

| RDKit Open-source cheminformatics and machine learning.

Loading...
Searching...
No Matches
ControlCHandler.h
Go to the documentation of this file.
1//
2// Copyright (C) David Cosgrove 2025.
3//
4// @@ All Rights Reserved @@
5// This file is part of the RDKit.
6// The contents are covered by the terms of the BSD license
7// which is included in the file license.txt, found at the root
8// of the RDKit source tree.
9//
10
11#ifndef CONTROLCHANDLER_H
12#define CONTROLCHANDLER_H
13
14#include <atomic>
15#include <csignal>
16#include <stdexcept>
17
18#include <RDGeneral/export.h>
19
20namespace RDKit {
21
22 class ControlCCaught : public std::runtime_error {
23 public:
24 explicit ControlCCaught()
25 : std::runtime_error("The process was interrupted with Ctrl+c") {};
26};
27
28//! This class catches a control-C/SIGINT and sets the flag d_gotSignal
29//! if one is received. It is intended to be used inside a long
30//! C++ calculation called from Python which intercepts the signal
31//! handler. The C++ code must check the value of d_gotSignal
32//! periodically and act accordingly. The destructor resets
33//! the signal handler and flag for next use, which is essential
34//! because it's a static variable.
35//! Example usage, inside a boost::python wrapper:
36//! ResultsObject results;
37//! {
38//! NOGIL gil;
39//! results = someFunction();
40//! }
41//! if (results.getCancelled()) {
42//! throw_runtime_error("someFunction cancelled");
43//! }
44//! It's important that the exception is thrown once the GIL has been
45//! released, otherwise a crash is inevitable at some future point.
46 class ControlCHandler {
47 public:
48 ControlCHandler() { d_prev_handler = std::signal(SIGINT, signalHandler); }
49 ControlCHandler(const ControlCHandler &) = delete;
50 ControlCHandler(ControlCHandler &&) = delete;
51 ControlCHandler &operator=(const ControlCHandler &) = delete;
52 ControlCHandler &operator=(ControlCHandler &&) = delete;
53 ~ControlCHandler() {
54 std::signal(SIGINT, d_prev_handler);
55 d_gotSignal = false;
56 }
57 static bool getGotSignal() { return d_gotSignal; }
58 static void signalHandler(int signalNumber) {
59 if (signalNumber == SIGINT) {
60 d_gotSignal = true;
61 std::signal(SIGINT, d_prev_handler);
62 }
63 }
64 static void reset() {
65 d_gotSignal = false;
66 std::signal(SIGINT, signalHandler);
67 }
68
69 private:
70 inline static bool d_gotSignal{false};
71 inline static void (*d_prev_handler)(int);
72};
73} // namespace RDKit
74#endif // CONTROLCHANDLER_H
RDKit::ControlCCaught::ControlCCaught
ControlCCaught()
Definition ControlCHandler.h:24
RDKit::ControlCHandler::ControlCHandler
ControlCHandler(ControlCHandler &&)=delete
RDKit::ControlCHandler::operator=
ControlCHandler & operator=(ControlCHandler &&)=delete
RDKit::ControlCHandler::~ControlCHandler
~ControlCHandler()
Definition ControlCHandler.h:53
RDKit::ControlCHandler::ControlCHandler
ControlCHandler(const ControlCHandler &)=delete
RDKit::ControlCHandler::operator=
ControlCHandler & operator=(const ControlCHandler &)=delete
RDKit::ControlCHandler::ControlCHandler
ControlCHandler()
Definition ControlCHandler.h:48
RDKit::ControlCHandler::reset
static void reset()
Definition ControlCHandler.h:64
RDKit::ControlCHandler::getGotSignal
static bool getGotSignal()
Definition ControlCHandler.h:57
RDKit::ControlCHandler::signalHandler
static void signalHandler(int signalNumber)
Definition ControlCHandler.h:58
export.h
RDKit
Std stuff.
Definition Abbreviations.h:19