| 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 | @@ -278,6 +278,15 @@ static void recreate_gil(struct _gil_runtime_state *gil) | |
| static void | ||
| drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) | ||
| { | ||
| /* If tstate is NULL, the caller is indicating that we're releasing | ||
| the GIL for the last time in this thread. This is particularly | ||
| relevant when the current thread state is finalizing or its | ||
| interpreter is finalizing (either may be in an inconsistent | ||
| state). In that case the current thread will definitely | ||
| never try to acquire the GIL again. */ | ||
| // XXX It may be more correct to check tstate->_status.finalizing. | ||
| // XXX assert(tstate == NULL || !tstate->_status.cleared); | ||
|
|
||
| struct _gil_runtime_state *gil = ceval->gil; | ||
| if (!_Py_atomic_load_relaxed(&gil->locked)) { | ||
| Py_FatalError("drop_gil: GIL is not locked"); | ||
| Expand All | @@ -298,7 +307,15 @@ drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) | |
| MUTEX_UNLOCK(gil->mutex); | ||
|
|
||
| #ifdef FORCE_SWITCHING | ||
| if (_Py_atomic_load_relaxed(&ceval->gil_drop_request) && tstate != NULL) { | ||
| /* We check tstate first in case we might be releasing the GIL for | ||
| the last time in this thread. In that case there's a possible | ||
| race with tstate->interp getting deleted after gil->mutex is | ||
| unlocked and before the following code runs, leading to a crash. | ||
| We can use (tstate == NULL) to indicate the thread is done with | ||
| the GIL, and that's the only time we might delete the | ||
| interpreter, so checking tstate first prevents the crash. | ||
| See https://github.com/python/cpython/issues/104341. */ | ||
| if (tstate != NULL && _Py_atomic_load_relaxed(&ceval->gil_drop_request)) { | ||
| MUTEX_LOCK(gil->switch_mutex); | ||
| /* Not switched yet => wait */ | ||
| if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) | ||
| Expand Down Expand Up | @@ -350,6 +367,9 @@ take_gil(PyThreadState *tstate) | |
| int err = errno; | ||
|
|
||
| assert(tstate != NULL); | ||
| /* We shouldn't be using a thread state that isn't viable any more. */ | ||
| // XXX It may be more correct to check tstate->_status.finalizing. | ||
| // XXX assert(!tstate->_status.cleared); | ||
|
|
||
| if (tstate_must_exit(tstate)) { | ||
| /* bpo-39877: If Py_Finalize() has been called and tstate is not the | ||
| Expand Down Expand Up | @@ -625,10 +645,12 @@ _PyEval_AcquireLock(PyThreadState *tstate) | |
| } | ||
|
|
||
| void | ||
| _PyEval_ReleaseLock(PyThreadState *tstate) | ||
| _PyEval_ReleaseLock(PyInterpreterState *interp, PyThreadState *tstate) | ||
|
Comment thread
Copy link
Copy Markdown
Member
Author
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 QualityThe other key part of this change is here, where we pass in the interpreter separately from the thread state, which allows tstate to be NULL.
Sorry, something went wrong.
All reactions
|
||
| { | ||
| _Py_EnsureTstateNotNULL(tstate); | ||
| struct _ceval_state *ceval = &tstate->interp->ceval; | ||
| /* If tstate is NULL then we do not expect the current thread | ||
| to acquire the GIL ever again. */ | ||
| assert(tstate == NULL || tstate->interp == interp); | ||
| struct _ceval_state *ceval = &interp->ceval; | ||
| drop_gil(ceval, tstate); | ||
| } | ||
|
|
||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.