diff options
author | Paul Sokolovsky <pfalcon@users.sourceforge.net> | 2015-12-23 00:06:37 +0200 |
---|---|---|
committer | Paul Sokolovsky <pfalcon@users.sourceforge.net> | 2015-12-23 00:07:00 +0200 |
commit | 1c9210bc2b58303c1df2ff287f17d178b1a2772b (patch) | |
tree | fb38fd67839a5738b43ca2a73a87a28938f2df8e /unix/unix_mphal.c | |
parent | e9751d2ac057070c52a7a67bd6e8b97e944ee088 (diff) | |
download | micropython-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/unix_mphal.c')
-rw-r--r-- | unix/unix_mphal.c | 10 |
1 files changed, 10 insertions, 0 deletions
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 |