cpython: f9461f1e0559 (original) (raw)
Mercurial > cpython
changeset 99999:f9461f1e0559 3.5
Add _PyThreadState_UncheckedGet() Issue #26154: Add a new private _PyThreadState_UncheckedGet() function which gets the current thread state, but don't call Py_FatalError() if it is NULL. Python 3.5.1 removed the _PyThreadState_Current symbol from the Python C API to no more expose complex and private atomic types. Atomic types depends on the compiler or can even depend on compiler options. The new function _PyThreadState_UncheckedGet() allows to get the variable value without having to care of the exact implementation of atomic types. Changes: * Replace direct usage of the _PyThreadState_Current variable with a call to _PyThreadState_UncheckedGet(). * In pystate.c, replace direct usage of the _PyThreadState_Current variable with the PyThreadState_GET() macro for readability. * Document also PyThreadState_Get() in pystate.h [#26154]
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Wed, 20 Jan 2016 11:12:38 +0100 |
parents | 6c624ba1b61e |
children | d4f13c9a2b07 32ee5d197500 |
files | Include/pystate.h Misc/NEWS Modules/faulthandler.c Objects/dictobject.c Python/errors.c Python/pystate.c Python/sysmodule.c |
diffstat | 7 files changed, 42 insertions(+), 26 deletions(-)[+] [-] Include/pystate.h 10 Misc/NEWS 7 Modules/faulthandler.c 2 Objects/dictobject.c 6 Python/errors.c 8 Python/pystate.c 33 Python/sysmodule.c 2 |
line wrap: on
line diff
--- a/Include/pystate.h +++ b/Include/pystate.h @@ -168,7 +168,17 @@ PyAPI_FUNC(void) PyThreadState_DeleteCur PyAPI_FUNC(void) _PyGILState_Reinit(void); #endif +/* Return the current thread state. The global interpreter lock must be held.
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,13 @@ Release date: tba Core and Builtins ----------------- +- Issue #26154: Add a new private _PyThreadState_UncheckedGet() function to get
- the current Python thread state, but don't issue a fatal error if it is NULL.
- This new function must be used instead of accessing directly the
- _PyThreadState_Current variable. The variable is no more exposed since
- Python 3.5.1 to hide the exact implementation of atomic C types, to avoid
- compiler issues. +
- Issue #25731: Fix set and deleting new on a class.
- Issue #22995: [UPDATE] Comment out the one of the pickleability tests in
--- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -490,7 +490,7 @@ faulthandler_thread(void unused) assert(st == PY_LOCK_FAILURE); / get the thread holding the GIL, NULL if no thread hold the GIL */
current = (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);[](#l3.7)
current = _PyThreadState_UncheckedGet();[](#l3.8)
_Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
--- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1064,8 +1064,7 @@ PyDict_GetItem(PyObject *op, PyObject *k Let's just hope that no exception occurs then... This must be _PyThreadState_Current and not PyThreadState_GET() because in debug mode, the latter complains if tstate is NULL. */
- tstate = _PyThreadState_UncheckedGet(); if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ PyObject *err_type, *err_value, *err_tb;
@@ -1102,8 +1101,7 @@ PyObject * Let's just hope that no exception occurs then... This must be _PyThreadState_Current and not PyThreadState_GET() because in debug mode, the latter complains if tstate is NULL. */
- tstate = _PyThreadState_UncheckedGet(); if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ PyObject *err_type, *err_value, *err_tb;
--- a/Python/errors.c +++ b/Python/errors.c @@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, con PyObject * PyErr_Occurred(void) {
- /* If there is no thread state, PyThreadState_GET calls
Py_FatalError, which calls PyErr_Occurred. To avoid the[](#l5.8)
resulting infinite loop, we inline PyThreadState_GET here and[](#l5.9)
treat no thread as no error. */[](#l5.10)
- PyThreadState *tstate =
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current));[](#l5.12)
- PyThreadState *tstate = _PyThreadState_UncheckedGet(); return tstate == NULL ? NULL : tstate->curexc_type; }
--- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,6 +3,12 @@ #include "Python.h" +#ifndef Py_BUILD_CORE +/* ensure that PyThreadState_GET() is a macro, not an alias to
#ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -437,8 +443,7 @@ PyThreadState_Delete(PyThreadState *tsta void PyThreadState_DeleteCurrent() {
- PyThreadState *tstate = PyThreadState_GET(); if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate");
@@ -489,10 +494,16 @@ void PyThreadState * +_PyThreadState_UncheckedGet(void) +{
+} + + +PyThreadState * PyThreadState_Get(void) {
- PyThreadState *tstate = PyThreadState_GET(); if (tstate == NULL) Py_FatalError("PyThreadState_Get: no current thread");
@@ -503,8 +514,7 @@ PyThreadState_Get(void) PyThreadState * PyThreadState_Swap(PyThreadState *newts) {
_Py_atomic_store_relaxed(&_PyThreadState_Current, newts); /* It should not be possible for more than one thread state @@ -535,8 +545,7 @@ PyThreadState_Swap(PyThreadState *newts) PyObject * PyThreadState_GetDict(void) {
@@ -682,7 +691,7 @@ PyThreadState_IsCurrent(PyThreadState t { / Must be the tstate for this thread */ assert(PyGILState_GetThisThreadState()==tstate);
} /* Internal initialization/finalization functions called by @@ -774,9 +783,7 @@ PyGILState_GetThisThreadState(void) int PyGILState_Check(void) {
- /* can't use PyThreadState_Get() since it will assert that it has the GIL */
- PyThreadState tstate = (PyThreadState)_Py_atomic_load_relaxed(
&_PyThreadState_Current);[](#l6.89)
- PyThreadState *tstate = PyThreadState_GET(); return tstate && (tstate == PyGILState_GetThisThreadState()); }
--- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1397,7 +1397,7 @@ error: Py_XDECREF(name); Py_XDECREF(value); /* No return value, therefore clear error state if possible */