Skip to content

Commit c8072e4

Browse files
committed
py/scheduler: Schedule SystemExit or SystemAbort.
This implements mp_sched_system_exit_or_abort(), which can be used to schedule a SystemExit or SystemAbort on the main thread. This can be used by async sources to exit MicroPython if requested by a firmware process. Use abort=true if the MicroPython script must not be able to catch it, not even with a bare except. The implementation is similar to mp_sched_keyboard_interrupt(). Signed-off-by: Laurens Valk <laurens@pybricks.com>
1 parent e40c35d commit c8072e4

File tree

6 files changed

+32
-3
lines changed

6 files changed

+32
-3
lines changed

py/mpconfig.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,8 @@
659659
#endif
660660

661661
// Whether to provide the SystemAbort exception, used to exit MicroPython
662-
// even if user code catches all exceptions.
662+
// even if user code catches all exceptions. This also provides
663+
// mp_sched_system_exit_or_abort() to schedule the mp_system_exception object.
663664
#ifndef MICROPY_ENABLE_SYSTEM_ABORT
664665
#define MICROPY_ENABLE_SYSTEM_ABORT (0)
665666
#endif

py/mpstate.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ typedef struct _mp_state_vm_t {
165165
mp_obj_exception_t mp_kbd_exception;
166166
#endif
167167

168+
#if MICROPY_ENABLE_SYSTEM_ABORT
169+
// exception object of type SystemExit or SystemAbort
170+
mp_obj_exception_t mp_system_exception;
171+
#endif
172+
168173
// dictionary with loaded modules (may be exposed as sys.modules)
169174
mp_obj_dict_t mp_loaded_modules_dict;
170175

py/objexcept.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,9 @@ MP_DEFINE_EXCEPTION(Exception, BaseException)
377377
*/
378378

379379
#if MICROPY_ENABLE_SYSTEM_ABORT
380-
// Exception that can't be raised or caught by user code, not even with a
381-
// bare except. Can be used to force MicroPython to exit from C code.
380+
// Exception that can't be raised or caught by user code, not even with a bare
381+
// except. Do not raise directly but use mp_sched_system_exit_or_abort(true) to
382+
// schedule it on the main thread.
382383
MP_DEFINE_EXCEPTION(SystemAbort, BaseException)
383384
#endif
384385

py/runtime.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ void mp_init(void) {
9595
MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj;
9696
#endif
9797

98+
#if MICROPY_ENABLE_SYSTEM_ABORT
99+
// initialise the exception object for raising SystemExit or SystemAbort
100+
MP_STATE_VM(mp_system_exception).traceback_alloc = 0;
101+
MP_STATE_VM(mp_system_exception).traceback_len = 0;
102+
MP_STATE_VM(mp_system_exception).traceback_data = NULL;
103+
MP_STATE_VM(mp_system_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj;
104+
#endif
105+
98106
#if MICROPY_ENABLE_COMPILER
99107
// optimization disabled by default
100108
MP_STATE_VM(mp_optimise_value) = 0;

py/runtime.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ void mp_deinit(void);
7575

7676
void mp_sched_exception(mp_obj_t exc);
7777
void mp_sched_keyboard_interrupt(void);
78+
#if MICROPY_ENABLE_SYSTEM_ABORT
79+
void mp_sched_system_exit_or_abort(bool abort);
80+
#endif
7881
void mp_handle_pending(bool raise_exc);
7982

8083
#if MICROPY_ENABLE_SCHEDULER

py/scheduler.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ void MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(mp_sched_keyboard_interrupt)(void)
5151
}
5252
#endif
5353

54+
#if MICROPY_ENABLE_SYSTEM_ABORT
55+
// Schedules SystemExit or SystemAbort on the main thread. Can be used by
56+
// async sources to exit MicroPython. Use abort=true if the MicroPython script
57+
// must not be able to catch it, not even with a bare except.
58+
void MICROPY_WRAP_MP_SCHED_EXCEPTION(mp_sched_system_exit_or_abort)(bool abort) {
59+
MP_STATE_VM(mp_system_exception).base.type = abort ?
60+
&mp_type_SystemAbort : &mp_type_SystemExit;
61+
mp_sched_exception(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_system_exception)));
62+
}
63+
#endif
64+
5465
#if MICROPY_ENABLE_SCHEDULER
5566

5667
#define IDX_MASK(i) ((i) & (MICROPY_SCHEDULER_DEPTH - 1))

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy