summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/mpconfig.h6
-rw-r--r--unix/mpconfigport.h1
-rw-r--r--unix/unix_mphal.c10
3 files changed, 17 insertions, 0 deletions
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 6de184a9c4..5e717ad0f6 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -371,6 +371,12 @@
# endif
#endif
+// Prefer to raise KeyboardInterrupt asynchronously (from signal or interrupt
+// handler) - if supported by a particular port.
+#ifndef MICROPY_ASYNC_KBD_INTR
+#define MICROPY_ASYNC_KBD_INTR (0)
+#endif
+
// Whether to include REPL helper function
#ifndef MICROPY_HELPER_REPL
#define MICROPY_HELPER_REPL (0)
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index a20f1c5094..a74345817d 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -128,6 +128,7 @@
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256)
+#define MICROPY_ASYNC_KBD_INTR (1)
extern const struct _mp_obj_module_t mp_module_machine;
extern const struct _mp_obj_module_t mp_module_os;
diff --git a/unix/unix_mphal.c b/unix/unix_mphal.c
index dbb6fbcdd4..8d3321ef66 100644
--- a/unix/unix_mphal.c
+++ b/unix/unix_mphal.c
@@ -37,12 +37,22 @@
STATIC void sighandler(int signum) {
if (signum == SIGINT) {
+ #if MICROPY_ASYNC_KBD_INTR
+ mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj));
+ sigset_t mask;
+ sigemptyset(&mask);
+ // On entry to handler, its signal is blocked, and unblocked on
+ // normal exit. As we instead perform longjmp, unblock it manually.
+ sigprocmask(SIG_SETMASK, &mask, NULL);
+ nlr_raise(MP_STATE_VM(keyboard_interrupt_obj));
+ #else
if (MP_STATE_VM(mp_pending_exception) == MP_STATE_VM(keyboard_interrupt_obj)) {
// this is the second time we are called, so die straight away
exit(1);
}
mp_obj_exception_clear_traceback(MP_STATE_VM(keyboard_interrupt_obj));
MP_STATE_VM(mp_pending_exception) = MP_STATE_VM(keyboard_interrupt_obj);
+ #endif
}
}
#endif