mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
py/scheduler: Allow selective handling in mp_handle_pending.
Extend mp_handle_pending to support three distinct behaviors via mp_handle_pending_internal(): - MP_HANDLE_PENDING_CALLBACKS_ONLY: process callbacks only - MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS: callbacks + raise exceptions - MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS: callbacks + clear only Original mp_handle_pending(bool) preserved as inline wrapper for backward compatibility. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
committed by
Damien George
parent
c91e091ad7
commit
c57aebf790
15
py/runtime.h
15
py/runtime.h
@@ -52,6 +52,12 @@ typedef enum {
|
||||
MP_ARG_KW_ONLY = 0x200,
|
||||
} mp_arg_flag_t;
|
||||
|
||||
typedef enum {
|
||||
MP_HANDLE_PENDING_CALLBACKS_ONLY,
|
||||
MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS,
|
||||
MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS,
|
||||
} mp_handle_pending_behaviour_t;
|
||||
|
||||
typedef union _mp_arg_val_t {
|
||||
bool u_bool;
|
||||
mp_int_t u_int;
|
||||
@@ -100,7 +106,14 @@ void mp_sched_keyboard_interrupt(void);
|
||||
#if MICROPY_ENABLE_VM_ABORT
|
||||
void mp_sched_vm_abort(void);
|
||||
#endif
|
||||
void mp_handle_pending(bool raise_exc);
|
||||
|
||||
void mp_handle_pending_internal(mp_handle_pending_behaviour_t behavior);
|
||||
|
||||
static inline void mp_handle_pending(bool raise_exc) {
|
||||
mp_handle_pending_internal(raise_exc ?
|
||||
MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS :
|
||||
MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS);
|
||||
}
|
||||
|
||||
#if MICROPY_ENABLE_SCHEDULER
|
||||
void mp_sched_lock(void);
|
||||
|
||||
@@ -213,24 +213,27 @@ MP_REGISTER_ROOT_POINTER(mp_sched_item_t sched_queue[MICROPY_SCHEDULER_DEPTH]);
|
||||
|
||||
// Called periodically from the VM or from "waiting" code (e.g. sleep) to
|
||||
// process background tasks and pending exceptions (e.g. KeyboardInterrupt).
|
||||
void mp_handle_pending(bool raise_exc) {
|
||||
void mp_handle_pending_internal(mp_handle_pending_behaviour_t behavior) {
|
||||
bool handle_exceptions = (behavior != MP_HANDLE_PENDING_CALLBACKS_ONLY);
|
||||
bool raise_exceptions = (behavior == MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS);
|
||||
|
||||
// Handle pending VM abort.
|
||||
#if MICROPY_ENABLE_VM_ABORT
|
||||
if (MP_STATE_VM(vm_abort) && mp_thread_is_main_thread()) {
|
||||
if (handle_exceptions && MP_STATE_VM(vm_abort) && mp_thread_is_main_thread()) {
|
||||
MP_STATE_VM(vm_abort) = false;
|
||||
if (raise_exc && nlr_get_abort() != NULL) {
|
||||
if (raise_exceptions && nlr_get_abort() != NULL) {
|
||||
nlr_jump_abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle any pending exception.
|
||||
if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) {
|
||||
if (handle_exceptions && MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) {
|
||||
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||
mp_obj_t obj = MP_STATE_THREAD(mp_pending_exception);
|
||||
if (obj != MP_OBJ_NULL) {
|
||||
MP_STATE_THREAD(mp_pending_exception) = MP_OBJ_NULL;
|
||||
if (raise_exc) {
|
||||
if (raise_exceptions) {
|
||||
MICROPY_END_ATOMIC_SECTION(atomic_state);
|
||||
nlr_raise(obj);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user