Skip to content

Commit c57aebf

Browse files
iabdalkaderdpgeorge
authored andcommitted
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 <[email protected]>
1 parent c91e091 commit c57aebf

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

py/runtime.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ typedef enum {
5252
MP_ARG_KW_ONLY = 0x200,
5353
} mp_arg_flag_t;
5454

55+
typedef enum {
56+
MP_HANDLE_PENDING_CALLBACKS_ONLY,
57+
MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS,
58+
MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS,
59+
} mp_handle_pending_behaviour_t;
60+
5561
typedef union _mp_arg_val_t {
5662
bool u_bool;
5763
mp_int_t u_int;
@@ -100,7 +106,14 @@ void mp_sched_keyboard_interrupt(void);
100106
#if MICROPY_ENABLE_VM_ABORT
101107
void mp_sched_vm_abort(void);
102108
#endif
103-
void mp_handle_pending(bool raise_exc);
109+
110+
void mp_handle_pending_internal(mp_handle_pending_behaviour_t behavior);
111+
112+
static inline void mp_handle_pending(bool raise_exc) {
113+
mp_handle_pending_internal(raise_exc ?
114+
MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS :
115+
MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS);
116+
}
104117

105118
#if MICROPY_ENABLE_SCHEDULER
106119
void mp_sched_lock(void);

py/scheduler.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,24 +213,27 @@ MP_REGISTER_ROOT_POINTER(mp_sched_item_t sched_queue[MICROPY_SCHEDULER_DEPTH]);
213213

214214
// Called periodically from the VM or from "waiting" code (e.g. sleep) to
215215
// process background tasks and pending exceptions (e.g. KeyboardInterrupt).
216-
void mp_handle_pending(bool raise_exc) {
216+
void mp_handle_pending_internal(mp_handle_pending_behaviour_t behavior) {
217+
bool handle_exceptions = (behavior != MP_HANDLE_PENDING_CALLBACKS_ONLY);
218+
bool raise_exceptions = (behavior == MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS);
219+
217220
// Handle pending VM abort.
218221
#if MICROPY_ENABLE_VM_ABORT
219-
if (MP_STATE_VM(vm_abort) && mp_thread_is_main_thread()) {
222+
if (handle_exceptions && MP_STATE_VM(vm_abort) && mp_thread_is_main_thread()) {
220223
MP_STATE_VM(vm_abort) = false;
221-
if (raise_exc && nlr_get_abort() != NULL) {
224+
if (raise_exceptions && nlr_get_abort() != NULL) {
222225
nlr_jump_abort();
223226
}
224227
}
225228
#endif
226229

227230
// Handle any pending exception.
228-
if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) {
231+
if (handle_exceptions && MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) {
229232
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
230233
mp_obj_t obj = MP_STATE_THREAD(mp_pending_exception);
231234
if (obj != MP_OBJ_NULL) {
232235
MP_STATE_THREAD(mp_pending_exception) = MP_OBJ_NULL;
233-
if (raise_exc) {
236+
if (raise_exceptions) {
234237
MICROPY_END_ATOMIC_SECTION(atomic_state);
235238
nlr_raise(obj);
236239
}

0 commit comments

Comments
 (0)