Skip to content

Commit 24aa6c2

Browse files
committed
Reinstall signal handler when Python signal handler called
1 parent fbfc559 commit 24aa6c2

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/cysignals/implementation.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,14 @@ static void setup_cysignals_handlers(void)
681681
sigprocmask(SIG_SETMASK, &default_sigmask, &sigmask_with_sigint);
682682
#endif
683683

684-
/* Install signal handlers */
684+
/* Install signal handlers. We need a separate C-level interrupt handler
685+
* apart from the Python-level interrupt handler because Python-level
686+
* interrupt handler will not be called inside Cython code.
687+
* See init_cysignals and python_check_interrupt for an explanation.
688+
* A downside is the C-level interrupt handler will be overwritten
689+
* when signal(SIGINT, getsignal(SIGINT)) is executed, in that case
690+
* init_cysignals() need to be called again.
691+
*/
685692
/* Handlers for interrupt-like signals */
686693
sa.sa_handler = cysigs_interrupt_handler;
687694
sa.sa_flags = 0;

src/cysignals/signals.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ cdef extern from "struct_signals.h":
2626

2727
ctypedef struct cysigs_t:
2828
cy_atomic_int sig_on_count
29+
cy_atomic_int interrupt_received
2930
cy_atomic_int block_sigint
3031
const char* s
3132
PyObject* exc_value

src/cysignals/signals.pyx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ def python_check_interrupt(sig, frame):
353353
``implementation.c``.
354354
"""
355355
sig_check()
356+
if cysigs.exc_value:
357+
return
358+
# If this line is reached, a possibility is that something called
359+
# signal(SIGINT, getsignal(SIGINT)), which cause cysigs_interrupt_handler
360+
# to not be called. We reinstall the C-level signal handler.
361+
init_cysignals()
362+
cysigs.interrupt_received = sig
363+
sig_check()
356364

357365

358366
cdef void verify_exc_value() noexcept:

0 commit comments

Comments
 (0)