8000 gh-105716: Update interp->threads.main After Fork (gh-117049) · python/cpython@5a76d1b · GitHub
[go: up one dir, main page]

Skip to content

Commit 5a76d1b

Browse files
gh-105716: Update interp->threads.main After Fork (gh-117049)
I missed this in gh-109921. We also update Py_Exit() to call _PyInterpreterState_SetNotRunningMain(), if necessary.
1 parent bbee57f commit 5a76d1b

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

Include/internal/pycore_pystate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ PyAPI_FUNC(void) _PyInterpreterState_SetNotRunningMain(PyInterpreterState *);
8383
PyAPI_FUNC(int) _PyInterpreterState_IsRunningMain(PyInterpreterState *);
8484
PyAPI_FUNC(int) _PyInterpreterState_FailIfRunningMain(PyInterpreterState *);
8585

86+
extern int _PyThreadState_IsRunningMain(PyThreadState *);
87+
extern void _PyInterpreterState_ReinitRunningMain(PyThreadState *);
88+
8689

8790
static inline const PyConfig *
8891
_Py_GetMainConfig(void)

Modules/posixmodule.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ PyOS_AfterFork_Child(void)
646646
PyThreadState *tstate = _PyThreadState_GET();
647647
_Py_EnsureTstateNotNULL(tstate);
648648

649+
assert(tstate->thread_id == PyThread_get_thread_ident());
649650
#ifdef PY_HAVE_THREAD_NATIVE_ID
650651
tstate->native_thread_id = PyThread_get_thread_native_id();
651652
#endif
@@ -655,6 +656,9 @@ PyOS_AfterFork_Child(void)
655656
_Py_qsbr_after_fork((_PyThreadStateImpl *)tstate);
656657
#endif
657658

659+
// Ideally we could guarantee tstate is running main.
660+
_PyInterpreterState_ReinitRunningMain(tstate);
661+
658662
status = _PyEval_ReInitThreads(tstate);
659663
if (_PyStatus_EXCEPTION(status)) {
660664
goto fatal_error;

Python/pylifecycle.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3138,6 +3138,10 @@ call_ll_exitfuncs(_PyRuntimeState *runtime)
31383138
void _Py_NO_RETURN
31393139
Py_Exit(int sts)
31403140
{
3141+
PyThreadState *tstate = _PyThreadState_GET();
3142+
if (tstate != NULL && _PyThreadState_IsRunningMain(tstate)) {
3143+
_PyInterpreterState_SetNotRunningMain(tstate->interp);
3144+
}
31413145
if (Py_FinalizeEx() < 0) {
31423146
sts = 120;
31433147
}

Python/pystate.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,30 @@ _PyInterpreterState_IsRunningMain(PyInterpreterState *interp)
10501050
return 0;
10511051
}
10521052

1053+
#ifndef NDEBUG
1054+
static int
1055+
is_running_main(PyThreadState *tstate)
1056+
{
1057+
if (tstate->interp->threads.main != NULL) {
1058+
return tstate == tstate->interp->threads.main;
1059+
}
1060+
return 0;
1061+
}
1062+
#endif
1063+
1064+
int
1065+
_PyThreadState_IsRunningMain(PyThreadState *tstate)
1066+
{
1067+
PyInterpreterState *interp = tstate->interp;
1068+
if (interp->threads.main != NULL) {
1069+
return tstate == interp->threads.main;
1070+
}
1071+
if (_Py_IsMainInterpreter(interp)) {
1072+
return tstate->thread_id == interp->runtime->main_thread;
1073+
}
1074+
return 0;
1075+
}
1076+
10531077
int
10541078
_PyInterpreterState_FailIfRunningMain(PyInterpreterState *interp)
10551079
{
@@ -1061,6 +1085,15 @@ _PyInterpreterState_FailIfRunningMain(PyInterpreterState *interp)
10611085
return 0;
10621086
}
10631087

1088+
void
1089+
_PyInterpreterState_ReinitRunningMain(PyThreadState *tstate)
1090+
{
1091+
PyInterpreterState *interp = tstate->interp;
1092+
if (interp->threads.main != tstate) {
1093+
interp->threads.main = NULL;
1094+
}
1095+
}
1096+
10641097

10651098
//----------
10661099
// accessors
@@ -1543,6 +1576,7 @@ PyThreadState_Clear(PyThreadState *tstate)
15431576
{
15441577
assert(tstate->_status.initialized && !tstate->_status.cleared);
15451578
assert(current_fast_get()->interp == tstate->interp);
1579+
assert(!is_running_main(tstate));
15461580
// XXX assert(!tstate->_status.bound || tstate->_status.unbound);
15471581
tstate->_status.finalizing = 1; // just in case
15481582

@@ -1641,6 +1675,7 @@ tstate_delete_common(PyThreadState *tstate)
16411675
assert(tstate->_status.cleared && !tstate->_status.finalized);
16421676
assert(tstate->state != _Py_THREAD_ATTACHED);
16431677
tstate_verify_not_active(tstate);
1678+
assert(!is_running_main(tstate));
16441679

16451680
PyInterpreterState *interp = tstate->interp;
16461681
if (interp == NULL) {

0 commit comments

Comments
 (0)
0