I'm working on some macros that will allow extensions to be
"interruptable" (i.e. with Ctrl-C). The idea came from SAGE but the
implementation is complicated by the possibility of threads and making
sure to handle clean-up code correctly when the interrupt returns.
I'd like to get this in to 1.0 final. Anything needed will not require
re-compilation of extension modules built for 1.0b2 however. This will
be strictly "extra" and if an extension module doesn't use it there will
be no problems.
Step 1:
Define the interface. Here are a couple of draft proposals. Please
comment on them.
1) General purpose interface
NPY_SIG_TRY {
[code]
}
NPY_SIG_EXCEPT(signum) {
[interrupt handling return]
}
NPY_SIG_ELSE
[normal return]
The idea of signum is to hold the signal actually caught.
2) Simpler interface
NPY_SIG_TRY {
[code]
}
NPY_SIG_EXCEPT_GOTO(label)
[normal return]
label:
[interrupt handling return]
C-extensions often use the notion of a label to handle failure code.
If anybody has any thoughts on this, they would be greatly appreciated.
Step 2:
Implementation. I have the idea to have a single interrupt handler
(defined globally in NumPy) that basically uses longjmp to return to the
section of code corresponding to the thread that is handling the
interrupt. I had thought to use a global variable containing a linked
list of jmp_buf structures with a thread-id attached
(PyThread_get_thread_ident()) so that the interrupt handler can search
it to see if the thread has registered a return location. If it has
not, then the intterupt handler will just return normally. In this way
a thread that calls setjmpbuf will be sure to return to the correct
place when it handles the interrupt.
Concern:
My thinking is that this mechanism should work whether or not the GIL is
held so that we don't have to worry about whether or not the GIL is held
except in the interrupt handling case (when Python exceptions are to be
set). But, honestly, this gets very confusing.
The sigjmp / longjmp mechanism for handling interrupts is not
recommended under windows (not sure about mingw), but there we could
possibly use Microsoft's __try and __except extension to implement.
Initially, it would be "un-implemented" on platforms where it didn't work.
Any comments are greatly appreciated
-Travis