| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -619,8 +619,12 @@ void | |
| PyOS_BeforeFork(void) | ||
| { | ||
| PyInterpreterState *interp = _PyInterpreterState_GET(); | ||
| assert(interp->runtime == &_PyRuntime); | ||
| run_at_forkers(interp->before_forkers, 1); | ||
|
|
||
| PyMutex_Lock(&_PyRuntime.os_fork.mutex); | ||
| _PyRuntime.os_fork.parent.tid = PyThread_get_thread_ident_ex(); | ||
|
|
||
| _PyImport_AcquireLock(interp); | ||
| _PyEval_StopTheWorldAll(&_PyRuntime); | ||
| HEAD_LOCK(&_PyRuntime); | ||
| Expand All | @@ -629,11 +633,17 @@ PyOS_BeforeFork(void) | |
| void | ||
| PyOS_AfterFork_Parent(void) | ||
| { | ||
| _PyRuntime.os_fork.parent = (struct _os_fork_parent){0}; | ||
|
|
||
| HEAD_UNLOCK(&_PyRuntime); | ||
| _PyEval_StartTheWorldAll(&_PyRuntime); | ||
|
|
||
| PyInterpreterState *interp = _PyInterpreterState_GET(); | ||
| assert(interp->runtime == &_PyRuntime); | ||
| _PyImport_ReleaseLock(interp); | ||
|
|
||
| PyMutex_Unlock(&_PyRuntime.os_fork.mutex); | ||
|
|
||
| run_at_forkers(interp->after_forkers_parent, 0); | ||
| } | ||
|
|
||
| Expand All | @@ -644,15 +654,25 @@ PyOS_AfterFork_Child(void) | |
| _PyRuntimeState *runtime = &_PyRuntime; | ||
|
|
||
| // re-creates runtime->interpreters.mutex (HEAD_UNLOCK) | ||
| status = _PyRuntimeState_ReInitThreads(runtime); | ||
| status = _PyRuntimeState_ReInitThreads( | ||
| runtime, runtime->os_fork.parent.tid); | ||
| if (_PyStatus_EXCEPTION(status)) { | ||
| goto fatal_error; | ||
| } | ||
|
|
||
| PyThreadState *tstate = _PyThreadState_GET(); | ||
| _Py_EnsureTstateNotNULL(tstate); | ||
| assert(tstate->interp->runtime == &_PyRuntime); | ||
|
|
||
| assert(tstate->thread_id == PyThread_get_thread_ident()); | ||
| // We cannot assume that the parent and child always have | ||
| // the same thread ID. | ||
| // See https://github.com/python/cpython/issues/126688. | ||
| if (_PyRuntime.os_fork.parent.tid != PyThread_get_thread_ident_ex()) { | ||
| tstate->thread_id = PyThread_get_thread_ident(); | ||
| } | ||
| else { | ||
| assert(tstate->thread_id == PyThread_get_thread_ident()); | ||
| } | ||
| #ifdef PY_HAVE_THREAD_NATIVE_ID | ||
| tstate->native_thread_id = PyThread_get_thread_native_id(); | ||
| #endif | ||
| Expand All | @@ -678,7 +698,6 @@ PyOS_AfterFork_Child(void) | |
| _PyEval_StartTheWorldAll(&_PyRuntime); | ||
| _PyThreadState_DeleteList(list); | ||
|
|
||
| _PyImport_ReInitLock(tstate->interp); | ||
| _PyImport_ReleaseLock(tstate->interp); | ||
|
|
||
| _PySignal_AfterFork(); | ||
| Expand All | @@ -694,6 +713,9 @@ PyOS_AfterFork_Child(void) | |
| goto fatal_error; | ||
| } | ||
|
|
||
| _PyRuntime.os_fork.parent = (struct _os_fork_parent){0}; | ||
| PyMutex_Unlock(&_PyRuntime.os_fork.mutex); | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualitythis might need to be done before _PyThreadState_DeleteList above to handle the very silly case of someone forking from a destructor and deadlocking? ("why is that even reasonable to support?" is valid...)
Sorry, something went wrong.
All reactions
|
||
|
|
||
| run_at_forkers(tstate->interp->after_forkers_child, 0); | ||
| return; | ||
|
|
||
| Expand Down | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -497,7 +497,8 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) | |
| /* This function is called from PyOS_AfterFork_Child to ensure that | ||
| newly created child processes do not share locks with the parent. */ | ||
| PyStatus | ||
| _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) | ||
| _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime, | ||
| PyThread_ident_t parent) | ||
| { | ||
| // This was initially set in _PyRuntimeState_Init(). | ||
| runtime->main_thread = PyThread_get_thread_ident(); | ||
| Expand All | @@ -515,6 +516,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) | |
| for (PyInterpreterState *interp = runtime->interpreters.head; | ||
| interp != NULL; interp = interp->next) | ||
| { | ||
| _PyImport_ReInitLock(interp, parent); | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualitywhy is this only being done when the GIL is disabled instead of always as it was in the past?
Sorry, something went wrong.
All reactions
|
||
| for (int i = 0; i < NUM_WEAKREF_LIST_LOCKS; i++) { | ||
| _PyMutex_at_fork_reinit(&interp->weakref_locks[i]); | ||
| } | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityadd a comment mentioning which call above is now responsible for doing this.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.