summaryrefslogtreecommitdiffstatshomepage
path: root/unix
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-12-23 00:06:37 +0200
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-12-23 00:07:00 +0200
commit1c9210bc2b58303c1df2ff287f17d178b1a2772b (patch)
treefb38fd67839a5738b43ca2a73a87a28938f2df8e /unix
parente9751d2ac057070c52a7a67bd6e8b97e944ee088 (diff)
downloadmicropython-1c9210bc2b58303c1df2ff287f17d178b1a2772b.tar.gz
micropython-1c9210bc2b58303c1df2ff287f17d178b1a2772b.zip
unix/unix_mphal: Raise KeyboardInterrupt straight from signal handler.
POSIX doesn't guarantee something like that to work, but it works on any system with careful signal implementation. Roughly, the requirement is that signal handler is executed in the context of the process, its main thread, etc. This is true for Linux. Also tested to work without issues on MacOSX.
Diffstat (limited to 'unix')
-rw-r--r--unix/mpconfigport.h1
-rw-r--r--unix/unix_mphal.c10
2 files changed, 11 insertions, 0 deletions
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