diff --git a/src/libAtomVM/context.c b/src/libAtomVM/context.c index 0e35082ad1..9019227a31 100644 --- a/src/libAtomVM/context.c +++ b/src/libAtomVM/context.c @@ -140,6 +140,13 @@ void context_destroy(Context *ctx) struct ListHead *processes_table_list = synclist_wrlock(&ctx->global->processes_table); UNUSED(processes_table_list); + // Remove from scheduling lists (waiting/ready/running). + // list_remove on a self-referential (already removed + re-initialized) node is a safe no-op. + SMP_SPINLOCK_LOCK(&ctx->global->processes_spinlock); + list_remove(&ctx->processes_list_head); + list_init(&ctx->processes_list_head); + SMP_SPINLOCK_UNLOCK(&ctx->global->processes_spinlock); + list_remove(&ctx->processes_table_head); // Ensure process is not registered diff --git a/src/libAtomVM/scheduler.c b/src/libAtomVM/scheduler.c index a856d60012..f78574a388 100644 --- a/src/libAtomVM/scheduler.c +++ b/src/libAtomVM/scheduler.c @@ -287,9 +287,6 @@ Context *scheduler_run(GlobalContext *global) // process signal messages and also empty outer list to inner list. scheduler_process_native_signal_messages(result); if (UNLIKELY(result->flags & Killed)) { - SMP_SPINLOCK_LOCK(&global->processes_spinlock); - list_remove(&result->processes_list_head); - SMP_SPINLOCK_UNLOCK(&global->processes_spinlock); context_destroy(result); } else { if (mailbox_has_next(&result->mailbox)) { @@ -429,6 +426,7 @@ void scheduler_terminate(Context *ctx) SMP_SPINLOCK_LOCK(&ctx->global->processes_spinlock); context_update_flags(ctx, ~NoFlags, Killed); list_remove(&ctx->processes_list_head); + list_init(&ctx->processes_list_head); SMP_SPINLOCK_UNLOCK(&ctx->global->processes_spinlock); if (!ctx->leader) { context_destroy(ctx);