5.3.9 Signal Handling

Suppose you have a Cython function like
def foo():
    cdef int n
    # Some long running code that gets compiled to pure C, e.g.,
    while True:
        n = n + 1
If you call foo from the Sage interpreter, then when Sage gets to the ``chunk of long-running C code'' pressing control-C will not interrupt the calculation. The only way to interrupt the calculation is to completely kill your running copy of Sage. What a wasteful pain--surely there is a better way!

Indeed, if you simply rewrite the above code as follows, then suddenly control-C will work fine!

def foo():
    cdef int n
    _sig_on
    while True:
        n = n + 1
    _sig_off
Note: In a .pyx file which will be part of the Sage library, you have to explicitly put something like include "../ext/interrupt.pxi" in your file, where you give in quotes the relative directory to SAGE_ROOT/devel/sage/sage/ext/interrupt.pxi.

In addition to SIGINT, any code wrapped in _sig_on and _sig_off also traps SIGABRT, SIGALRM, SIGSEV, and SIGFPE.

IMPORTANT NOTES:

  1. These must always come in pairs. E.g., if you have just a _sig_off without a corresponding _sig_on, then control-C later in the interpreter will segfault!

  2. Do not put these in the __init__ method of a Cython extension class, or you'll get crashes.

  3. Do not put these around any Cython code that calls into the Python API (i.e., the generated C code should have no calls to the Python library)!!

  4. If you need to do a check of control-C inside a loop, e.g., when constructing a matrix, put _sig_check instead of using _sig_on then _sig_off.

See About this document... for information on suggesting changes.