I’m calling a few long-running things in C++, which I would like to be able to abort by pressing CTRL-C. The problem is that I can’t see any way of setting up a signal handler with ROOT. I tried something like the following:
hitting CTRL-C during the run of C++ won’t yield a decent location to continue, so what I usually do is CTRL-\ (SIGQUIT) which python leaves alone and results in an abort. The calls “sh.Add()” and “ROOT.gSystem.AddSignalHandler(sh)” are equivalent, so only one is needed. The use of TROOT::SetInterrupt() would not work since python starts up a separate thread that calls TSystem::ProcessEvents() which resets gROOT’s interrupt on each call. I’m not too familiar with Connect, but I think that the second argument should be the class of the third argument, which should be an object (so “TROOT” and ROOT.gROOT, respectively in your example).
For a proof of concept, please run the following code:[code]import ROOT
sh = ROOT.TSignalHandler( ROOT.kSigInterrupt, False )
sh.Add()
print ROOT.gROOT.IsBatch()
sh.Connect( “Notified()”, “TROOT”, ROOT.gROOT, “SetBatch()” )[/code]from a file onto an interactive python session in non-batch mode. A printout of ‘0’ should appear. Then continue by hitting CTRL-C: nothing should happen, whereas normal python behavior is to show a KeyboardInterrupt. Then do “print ROOT.gROOT.IsBatch()” which should now give you the printout ‘1’.
the gROOT fInterrupt will be set just fine if “SetInterrupt()” is used instead of the proof-of-concept “SetBatch()” in the example. Just that it will be erased in many different places in the ROOT sources (just do a grep on SetInterrupt), most notably in TSystem::ProcessEvents. You could use it anyway and hit CTRL-C a couple of times until you get lucky. In fact, in an interactive program, where there is a single dispatch to a long-winding C++ function, everything works as expected b/c the GIL is not released.
For example, file peter.C:[code]#include “TROOT.h” #include
void runforever() {
for ( int i = 0; ; ++i ) {
std::cout << "running: " << i << std::endl;
if ( gROOT->IsInterrupted() ) {
std::cout << “stopped!” << std::endl;
break;
}
}
}[/code]
and file peter.py:[code]import ROOT
ROOT.gROOT.LoadMacro( “peter.C+” )
sh = ROOT.TSignalHandler( ROOT.kSigInterrupt, False )
sh.Add()
sh.Connect( “Notified()”, “TROOT”, ROOT.gROOT, “SetInterrupt()” )
ROOT.runforever()[/code]
followed by running: $ python -i peter.py
behaves as expected when CTRL-C is hit.