summaryrefslogtreecommitdiff
path: root/Python/pystate.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c78
1 files changed, 54 insertions, 24 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 2ac2fd5274..24e20c3e23 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -3,6 +3,14 @@
#include "Python.h"
+#define GET_TSTATE() \
+ ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
+#define SET_TSTATE(value) \
+ _Py_atomic_store_relaxed(&_PyThreadState_Current, (Py_uintptr_t)(value))
+#define GET_INTERP_STATE() \
+ (GET_TSTATE()->interp)
+
+
/* --------------------------------------------------------------------------
CAUTION
@@ -48,7 +56,7 @@ static PyInterpreterState *interp_head = NULL;
/* Assuming the current thread holds the GIL, this is the
PyThreadState for the current thread. */
-_Py_atomic_address _PyThreadState_Current = {NULL};
+_Py_atomic_address _PyThreadState_Current = {0};
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
#ifdef WITH_THREAD
@@ -212,6 +220,9 @@ new_threadstate(PyInterpreterState *interp, int init)
tstate->on_delete = NULL;
tstate->on_delete_data = NULL;
+ tstate->coroutine_wrapper = NULL;
+ tstate->in_coroutine_wrapper = 0;
+
if (init)
_PyThreadState_Init(tstate);
@@ -251,8 +262,11 @@ PyObject*
PyState_FindModule(struct PyModuleDef* module)
{
Py_ssize_t index = module->m_base.m_index;
- PyInterpreterState *state = PyThreadState_GET()->interp;
+ PyInterpreterState *state = GET_INTERP_STATE();
PyObject *res;
+ if (module->m_slots) {
+ return NULL;
+ }
if (index == 0)
return NULL;
if (state->modules_by_index == NULL)
@@ -266,9 +280,17 @@ PyState_FindModule(struct PyModuleDef* module)
int
_PyState_AddModule(PyObject* module, struct PyModuleDef* def)
{
- PyInterpreterState *state = PyThreadState_GET()->interp;
- if (!def)
+ PyInterpreterState *state;
+ if (!def) {
+ assert(PyErr_Occurred());
+ return -1;
+ }
+ if (def->m_slots) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyState_AddModule called on module with slots");
return -1;
+ }
+ state = GET_INTERP_STATE();
if (!state->modules_by_index) {
state->modules_by_index = PyList_New(0);
if (!state->modules_by_index)
@@ -286,7 +308,7 @@ int
PyState_AddModule(PyObject* module, struct PyModuleDef* def)
{
Py_ssize_t index;
- PyInterpreterState *state = PyThreadState_GET()->interp;
+ PyInterpreterState *state = GET_INTERP_STATE();
if (!def) {
Py_FatalError("PyState_AddModule: Module Definition is NULL");
return -1;
@@ -306,8 +328,14 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def)
int
PyState_RemoveModule(struct PyModuleDef* def)
{
+ PyInterpreterState *state;
Py_ssize_t index = def->m_base.m_index;
- PyInterpreterState *state = PyThreadState_GET()->interp;
+ if (def->m_slots) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyState_RemoveModule called on module with slots");
+ return -1;
+ }
+ state = GET_INTERP_STATE();
if (index == 0) {
Py_FatalError("PyState_RemoveModule: Module index invalid.");
return -1;
@@ -327,7 +355,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
void
_PyState_ClearModules(void)
{
- PyInterpreterState *state = PyThreadState_GET()->interp;
+ PyInterpreterState *state = GET_INTERP_STATE();
if (state->modules_by_index) {
Py_ssize_t i;
for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
@@ -372,6 +400,8 @@ PyThreadState_Clear(PyThreadState *tstate)
tstate->c_tracefunc = NULL;
Py_CLEAR(tstate->c_profileobj);
Py_CLEAR(tstate->c_traceobj);
+
+ Py_CLEAR(tstate->coroutine_wrapper);
}
@@ -403,7 +433,7 @@ tstate_delete_common(PyThreadState *tstate)
void
PyThreadState_Delete(PyThreadState *tstate)
{
- if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current))
+ if (tstate == GET_TSTATE())
Py_FatalError("PyThreadState_Delete: tstate is still current");
#ifdef WITH_THREAD
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
@@ -417,12 +447,11 @@ PyThreadState_Delete(PyThreadState *tstate)
void
PyThreadState_DeleteCurrent()
{
- PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *tstate = GET_TSTATE();
if (tstate == NULL)
Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate");
- _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
+ SET_TSTATE(NULL);
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
tstate_delete_common(tstate);
@@ -469,10 +498,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
PyThreadState *
+_PyThreadState_UncheckedGet(void)
+{
+ return GET_TSTATE();
+}
+
+
+PyThreadState *
PyThreadState_Get(void)
{
- PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *tstate = GET_TSTATE();
if (tstate == NULL)
Py_FatalError("PyThreadState_Get: no current thread");
@@ -483,10 +518,9 @@ PyThreadState_Get(void)
PyThreadState *
PyThreadState_Swap(PyThreadState *newts)
{
- PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *oldts = GET_TSTATE();
- _Py_atomic_store_relaxed(&_PyThreadState_Current, newts);
+ SET_TSTATE(newts);
/* It should not be possible for more than one thread state
to be used for a thread. Check this the best we can in debug
builds.
@@ -515,8 +549,7 @@ PyThreadState_Swap(PyThreadState *newts)
PyObject *
PyThreadState_GetDict(void)
{
- PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
- &_PyThreadState_Current);
+ PyThreadState *tstate = GET_TSTATE();
if (tstate == NULL)
return NULL;
@@ -540,8 +573,7 @@ PyThreadState_GetDict(void)
int
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
- PyThreadState *tstate = PyThreadState_GET();
- PyInterpreterState *interp = tstate->interp;
+ PyInterpreterState *interp = GET_INTERP_STATE();
PyThreadState *p;
/* Although the GIL is held, a few C API functions can be called
@@ -662,7 +694,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
{
/* Must be the tstate for this thread */
assert(PyGILState_GetThisThreadState()==tstate);
- return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current);
+ return tstate == GET_TSTATE();
}
/* Internal initialization/finalization functions called by
@@ -754,9 +786,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);
+ PyThreadState *tstate = GET_TSTATE();
return tstate && (tstate == PyGILState_GetThisThreadState());
}