I am developing a standalone multi-threaded application that sorts a data stream into ROOT histograms. I use my own thread class. In addition I install my own signal handlers using sigaction directly. I use gSystem->ResetSignal() to reclaim signal handling from ROOT. Everything works as I expect until I open a TFile. At which point, my signal handling routines are lost. Instead of catching a SIGINT, a ctrl-C kills off the application without any messages, returning me to the shell.
If I comment out the TFile statements: opening the file, writing the objects to it, etc., then everything works as before.
The TFile is opened in the sorting thread.
I have tested the possibility that TFile resets my signal handler in a simple non-threaded program. But, this is not so. In this case, my signal handlers still work after I reclaim them from gSystem.
Looking at the ROOT source code, it appears that TFile requires gROOT. And it appears that gROOT does an InitSystem which might possibly reset the signal handlers after I have set them. But my simple non-threaded test program contradicts this.
Can someone give me pointers where I might look? I am using 5.26.00c.
there’s another set of signal handlers for the prompt interface. But that should chain the signal handlers, and I don’t see why it would get initialized at all for TFile. It depends on which libraries you link against, though.
You should be able to initialize a TApplication object yourself; no signal handlers should be replaced once you have created that object.
Of course we could debug this properly if you send us a test case that reproduces the issue.
The tarball for my app is at
webapps.anl.gov/filetransfer/do … 243183562/
There is a README with instructions on building the with/without TFile versions. I’d appreciate any help you can provide.
TFile::Write() calls IgnoreSignal(true), writes, and then calls IgnoreSignal(false). You start with ignoring SIGINT (before it’s set). TUnixSystem is not using a stack of ignores signal handlers but only a “previous value”. So what happens is:
1: your main: ignore SIGINT (which was 0, so the value of the ignored sig handler is 0)
2: your main: set SIGINT
3: TFile::Write: ignore SIGINT (but it was already ignored and this becomes a no-op)
4: TFile::Write: re-enable SIGINT (TUnixSystem stored 0 as sighandler in 1, so 0 gets “restored”)
The solution is to not call IgnoreSignals() in your main. I don’t see why it would be needed anyway: you do not want these signals to be ignored…
Thank you for your prompt attention to my problem. It was what I needed to get my program behaviour back.