gh-116522: Refactor _PyThreadState_DeleteExcept (#117131)

Split `_PyThreadState_DeleteExcept` into two functions:

- `_PyThreadState_RemoveExcept` removes all thread states other than one
  passed as an argument. It returns the removed thread states as a
  linked list.

- `_PyThreadState_DeleteList` deletes those dead thread states. It may
  call destructors, so we want to "start the world" before calling
  `_PyThreadState_DeleteList` to avoid potential deadlocks.
This commit is contained in:
Sam Gross 2024-03-21 14:21:02 -04:00 committed by GitHub
parent 50369e6c34
commit 1f72fb5447
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 41 additions and 23 deletions

View file

@ -664,6 +664,14 @@ PyOS_AfterFork_Child(void)
goto fatal_error;
}
// Remove the dead thread states. We "start the world" once we are the only
// thread state left to undo the stop the world call in `PyOS_BeforeFork`.
// That needs to happen before `_PyThreadState_DeleteList`, because that
// may call destructors.
PyThreadState *list = _PyThreadState_RemoveExcept(tstate);
_PyEval_StartTheWorldAll(&_PyRuntime);
_PyThreadState_DeleteList(list);
status = _PyImport_ReInitLock(tstate->interp);
if (_PyStatus_EXCEPTION(status)) {
goto fatal_error;