[Python-checkins] cpython (merge 3.5 -> default): Merge 3.5
victor.stinner
python-checkins at python.org
Wed Jan 20 05:20:43 EST 2016
https://hg.python.org/cpython/rev/d4f13c9a2b07
changeset: 100000:d4f13c9a2b07
parent: 99998:72034327022e
parent: 99999:f9461f1e0559
user: Victor Stinner <victor.stinner at gmail.com>
date: Wed Jan 20 11:19:46 2016 +0100
summary:
Merge 3.5
Issue #26154: Add a new private _PyThreadState_UncheckedGet() function.
files:
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 +-
7 files changed, 42 insertions(+), 26 deletions(-)
diff --git a/Include/pystate.h b/Include/pystate.h
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -168,7 +168,17 @@
PyAPI_FUNC(void) _PyGILState_Reinit(void);
#endif
+/* Return the current thread state. The global interpreter lock must be held.
+ * When the current thread state is NULL, this issues a fatal error (so that
+ * the caller needn't check for NULL). */
PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
+
+#ifdef WITH_THREAD
+/* Similar to PyThreadState_Get(), but don't issue a fatal error
+ * if it is NULL. */
+PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
+#endif
+
PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *);
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,13 @@
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 #25791: Trying to resolve a relative import without __spec__ or
__package__ defined now raises an ImportWarning
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -490,7 +490,7 @@
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);
+ current = _PyThreadState_UncheckedGet();
_Py_write_noraise(thread.fd, thread.header, (int)thread.header_len);
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1064,8 +1064,7 @@
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*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ 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 @@
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*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ tstate = _PyThreadState_UncheckedGet();
if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */
PyObject *err_type, *err_value, *err_tb;
diff --git a/Python/errors.c b/Python/errors.c
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -152,13 +152,7 @@
PyObject *
PyErr_Occurred(void)
{
- /* If there is no thread state, PyThreadState_GET calls
- Py_FatalError, which calls PyErr_Occurred. To avoid the
- resulting infinite loop, we inline PyThreadState_GET here and
- treat no thread as no error. */
- PyThreadState *tstate =
- ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current));
-
+ PyThreadState *tstate = _PyThreadState_UncheckedGet();
return tstate == NULL ? NULL : tstate->curexc_type;
}
diff --git a/Python/pystate.c b/Python/pystate.c
--- 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
+ * PyThreadState_Get() */
+# error "pystate.c must be compiled with Py_BUILD_CORE defined"
+#endif
+
/* --------------------------------------------------------------------------
CAUTION
@@ -423,7 +429,7 @@
void
PyThreadState_Delete(PyThreadState *tstate)
{
- if (tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
+ if (tstate == PyThreadState_GET())
Py_FatalError("PyThreadState_Delete: tstate is still current");
#ifdef WITH_THREAD
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
@@ -437,8 +443,7 @@
void
PyThreadState_DeleteCurrent()
{
- PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL)
Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate");
@@ -489,10 +494,16 @@
PyThreadState *
+_PyThreadState_UncheckedGet(void)
+{
+ return PyThreadState_GET();
+}
+
+
+PyThreadState *
PyThreadState_Get(void)
{
- PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL)
Py_FatalError("PyThreadState_Get: no current thread");
@@ -503,8 +514,7 @@
PyThreadState *
PyThreadState_Swap(PyThreadState *newts)
{
- PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *oldts = PyThreadState_GET();
_Py_atomic_store_relaxed(&_PyThreadState_Current, newts);
/* It should not be possible for more than one thread state
@@ -535,8 +545,7 @@
PyObject *
PyThreadState_GetDict(void)
{
- PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL)
return NULL;
@@ -682,7 +691,7 @@
{
/* Must be the tstate for this thread */
assert(PyGILState_GetThisThreadState()==tstate);
- return tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);
+ return tstate == PyThreadState_GET();
}
/* Internal initialization/finalization functions called by
@@ -774,9 +783,7 @@
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);
+ PyThreadState *tstate = PyThreadState_GET();
return tstate && (tstate == PyGILState_GetThisThreadState());
}
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1396,7 +1396,7 @@
Py_XDECREF(name);
Py_XDECREF(value);
/* No return value, therefore clear error state if possible */
- if (_Py_atomic_load_relaxed(&_PyThreadState_Current))
+ if (_PyThreadState_UncheckedGet())
PyErr_Clear();
}
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list