Skip to content

Commit fda9886

Browse files
committed
Add PyInterpreterState_Lookup()
1 parent 82b5b9f commit fda9886

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

Include/cpython/pystate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
283283
* PyThreadState_Ensure() or PyInterpreterState_Release(). */
284284
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Hold(void);
285285

286+
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Lookup(int64_t interp_id);
287+
286288
/* Release a reference to an interpreter incremented by PyInterpreterState_Hold() */
287289
PyAPI_FUNC(void) PyInterpreterState_Release(PyInterpreterState *interp);
288290

Python/pystate.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3074,9 +3074,6 @@ _PyThreadState_CheckConsistency(PyThreadState *tstate)
30743074
int
30753075
_PyThreadState_MustExit(PyThreadState *tstate)
30763076
{
3077-
if (!tstate->daemon) {
3078-
return 0;
3079-
}
30803077
int state = _Py_atomic_load_int_relaxed(&tstate->state);
30813078
return state == _Py_THREAD_SHUTTING_DOWN;
30823079
}
@@ -3221,6 +3218,29 @@ PyInterpreterState_Hold(void)
32213218
return interp;
32223219
}
32233220

3221+
PyInterpreterState *
3222+
PyInterpreterState_Lookup(int64_t interp_id)
3223+
{
3224+
PyInterpreterState *interp = _PyInterpreterState_LookUpID(interp_id);
3225+
if (interp == NULL) {
3226+
return NULL;
3227+
}
3228+
HEAD_LOCK(&_PyRuntime); // Prevent deletion
3229+
struct _Py_finalizing_threads finalizing = interp->threads.finalizing;
3230+
PyMutex *mutex = &finalizing.mutex;
3231+
PyMutex_Lock(mutex); // Synchronize TOCTOU with the event flag
3232+
if (_PyEvent_IsSet(&finalizing.finished)) {
3233+
/* Interpreter has already finished threads */
3234+
interp = NULL;
3235+
} else {
3236+
_Py_atomic_add_ssize(&finalizing.countdown, 1);
3237+
}
3238+
PyMutex_Unlock(mutex);
3239+
HEAD_UNLOCK(&_PyRuntime);
3240+
3241+
return interp;
3242+
}
3243+
32243244
void
32253245
PyInterpreterState_Release(PyInterpreterState *interp)
32263246
{

0 commit comments

Comments
 (0)