Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a deadlock where JIT executor drain could run under the rutime lock when
invalidations overflow the pending list.
13 changes: 12 additions & 1 deletion Python/optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,17 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp)
interp->executor_deletion_list_remaining_capacity = EXECUTOR_DELETE_LIST_MAX;
}

static inline int
can_clear_executor_deletion_list(PyInterpreterState *interp)
{
#ifdef Py_GIL_DISABLED
if (_PyRuntime.stoptheworld.world_stopped || interp->stoptheworld.world_stopped) {
return 0;
}
#endif
return 1;
}

static void
add_to_pending_deletion_list(_PyExecutorObject *self)
{
Expand All @@ -302,7 +313,7 @@ add_to_pending_deletion_list(_PyExecutorObject *self)
if (interp->executor_deletion_list_remaining_capacity > 0) {
interp->executor_deletion_list_remaining_capacity--;
}
else {
else if (can_clear_executor_deletion_list(interp)) {
_Py_ClearExecutorDeletionList(interp);
}
}
Expand Down
12 changes: 12 additions & 0 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -2358,6 +2358,18 @@ start_the_world(struct _stoptheworld_state *stw)
_PyRuntimeState *runtime = &_PyRuntime;
assert(PyMutex_IsLocked(&stw->mutex));

#ifdef _Py_TIER2
if (stw->is_global) {
_Py_FOR_EACH_STW_INTERP(stw, interp) {
_Py_ClearExecutorDeletionList(interp);
}
}
else {
PyInterpreterState *interp = _Py_CONTAINER_OF(stw, PyInterpreterState, stoptheworld);
_Py_ClearExecutorDeletionList(interp);
}
#endif

HEAD_LOCK(runtime);
stw->requested = 0;
stw->world_stopped = 0;
Expand Down
Loading