From a60fd7e6a8f59fb3f0fb7feae62c8a8df9ca33e7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 16 Feb 2015 09:40:12 +0200 Subject: Fixed few compiler warnings. --- Python/pystate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 2ac2fd5274..32a635c789 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -403,7 +403,7 @@ tstate_delete_common(PyThreadState *tstate) void PyThreadState_Delete(PyThreadState *tstate) { - if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current)) + if (tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) Py_FatalError("PyThreadState_Delete: tstate is still current"); #ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -662,7 +662,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 == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); } /* Internal initialization/finalization functions called by -- cgit v1.2.1 From 6139bc8c6c02db0e084b495d1fe5ac9707635ecb Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 6 Mar 2015 14:47:02 -0800 Subject: Issue #23524: Replace _PyVerify_fd function with calling _set_thread_local_invalid_parameter_handler on every thread. --- Python/pystate.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 32a635c789..ee1e469635 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -22,6 +22,12 @@ to avoid the expense of doing their own locking). #endif #endif +#if defined _MSC_VER && _MSC_VER >= 1900 +/* Issue #23524: Temporary fix to disable termination due to invalid parameters */ +PyAPI_DATA(void*) _Py_silent_invalid_parameter_handler; +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -222,6 +228,11 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); + +#if defined _MSC_VER && _MSC_VER >= 1900 + /* Issue #23524: Temporary fix to disable termination due to invalid parameters */ + _set_thread_local_invalid_parameter_handler((_invalid_parameter_handler)_Py_silent_invalid_parameter_handler); +#endif } return tstate; -- cgit v1.2.1 From ab401006bd13992bf70ebf394f974c20001c2f4f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 Mar 2015 21:53:15 +0200 Subject: Removed unintentional trailing spaces in non-external and non-generated C files. --- Python/pystate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index ee1e469635..926ef07e21 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -228,7 +228,7 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); - + #if defined _MSC_VER && _MSC_VER >= 1900 /* Issue #23524: Temporary fix to disable termination due to invalid parameters */ _set_thread_local_invalid_parameter_handler((_invalid_parameter_handler)_Py_silent_invalid_parameter_handler); -- cgit v1.2.1 From e07a52f272f00b6707b40f557e481749b73dd0fd Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Sun, 12 Apr 2015 00:26:27 -0400 Subject: Issue #23524: Replace _PyVerify_fd function with calls to _set_thread_local_invalid_parameter_handler. --- Python/pystate.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 926ef07e21..32a635c789 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -22,12 +22,6 @@ to avoid the expense of doing their own locking). #endif #endif -#if defined _MSC_VER && _MSC_VER >= 1900 -/* Issue #23524: Temporary fix to disable termination due to invalid parameters */ -PyAPI_DATA(void*) _Py_silent_invalid_parameter_handler; -#include -#endif - #ifdef __cplusplus extern "C" { #endif @@ -228,11 +222,6 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->next->prev = tstate; interp->tstate_head = tstate; HEAD_UNLOCK(); - -#if defined _MSC_VER && _MSC_VER >= 1900 - /* Issue #23524: Temporary fix to disable termination due to invalid parameters */ - _set_thread_local_invalid_parameter_handler((_invalid_parameter_handler)_Py_silent_invalid_parameter_handler); -#endif } return tstate; -- cgit v1.2.1 From ea639832c36905ecb07caba111f614c4bbf9bdd6 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 11 May 2015 22:57:16 -0400 Subject: PEP 0492 -- Coroutines with async and await syntax. Issue #24017. --- Python/pystate.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 32a635c789..e214f50497 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -212,6 +212,8 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->on_delete = NULL; tstate->on_delete_data = NULL; + tstate->coroutine_wrapper = NULL; + if (init) _PyThreadState_Init(tstate); @@ -372,6 +374,8 @@ PyThreadState_Clear(PyThreadState *tstate) tstate->c_tracefunc = NULL; Py_CLEAR(tstate->c_profileobj); Py_CLEAR(tstate->c_traceobj); + + Py_CLEAR(tstate->coroutine_wrapper); } -- cgit v1.2.1 From 599ed75a674f7ad2c983783ed6f3a75bd5ccae18 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 23 May 2015 22:24:10 +1000 Subject: PEP 489: Multi-phase extension module initialization Known limitations of the current implementation: - documentation changes are incomplete - there's a reference leak I haven't tracked down yet The leak is most visible by running: ./python -m test -R3:3 test_importlib However, you can also see it by running: ./python -X showrefcount Importing the array or _testmultiphase modules, and then deleting them from both sys.modules and the local namespace shows significant increases in the total number of active references each cycle. By contrast, with _testcapi (which continues to use single-phase initialisation) the global refcounts stabilise after a couple of cycles. --- Python/pystate.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index e214f50497..4ac05d6625 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -255,6 +255,9 @@ PyState_FindModule(struct PyModuleDef* module) Py_ssize_t index = module->m_base.m_index; PyInterpreterState *state = PyThreadState_GET()->interp; PyObject *res; + if (module->m_slots) { + return NULL; + } if (index == 0) return NULL; if (state->modules_by_index == NULL) @@ -268,7 +271,13 @@ PyState_FindModule(struct PyModuleDef* module) int _PyState_AddModule(PyObject* module, struct PyModuleDef* def) { - PyInterpreterState *state = PyThreadState_GET()->interp; + PyInterpreterState *state; + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_AddModule called on module with slots"); + return -1; + } + state = PyThreadState_GET()->interp; if (!def) return -1; if (!state->modules_by_index) { @@ -308,8 +317,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 = PyThreadState_GET()->interp; if (index == 0) { Py_FatalError("PyState_RemoveModule: Module index invalid."); return -1; -- cgit v1.2.1 From f28b7448cd4c7d325fee3c4bf4584f655eafccdb Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Tue, 2 Jun 2015 18:43:51 -0400 Subject: Issue 24342: Let wrapper set by sys.set_coroutine_wrapper fail gracefully --- Python/pystate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 4ac05d6625..7e0267ae1d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -213,6 +213,7 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->on_delete_data = NULL; tstate->coroutine_wrapper = NULL; + tstate->in_coroutine_wrapper = 0; if (init) _PyThreadState_Init(tstate); -- cgit v1.2.1 From b3b0102d41c7b1a25493b51d5d83d080fb32735b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 20 Jan 2016 11:12:38 +0100 Subject: 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 --- Python/pystate.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 7e0267ae1d..83f15fd671 100644 --- 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 @@ tstate_delete_common(PyThreadState *tstate) 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 @@ PyThreadState_Delete(PyThreadState *tstate) 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"); @@ -488,11 +493,17 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) } +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_Get(void) 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 @@ PyThreadState_Swap(PyThreadState *newts) 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 @@ PyThreadState_IsCurrent(PyThreadState *tstate) { /* 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 @@ 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 = PyThreadState_GET(); return tstate && (tstate == PyGILState_GetThisThreadState()); } -- cgit v1.2.1 From 5f6c81b82a13a1907246b063d30d9555e6e64177 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 22 Jan 2016 14:09:55 +0100 Subject: Use Py_uintptr_t for atomic pointers Issue #26161: Use Py_uintptr_t instead of void* for atomic pointers in pyatomic.h. Use atomic_uintptr_t when is used. Using void* causes compilation warnings depending on which implementation of atomic types is used. --- Python/pystate.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 83f15fd671..6d1c6d0a1f 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,11 +3,13 @@ #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 +#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 @@ -54,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 @@ -260,7 +262,7 @@ 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; @@ -284,7 +286,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def) "PyState_AddModule called on module with slots"); return -1; } - state = PyThreadState_GET()->interp; + state = GET_INTERP_STATE(); if (!def) return -1; if (!state->modules_by_index) { @@ -304,7 +306,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; @@ -331,7 +333,7 @@ PyState_RemoveModule(struct PyModuleDef* def) "PyState_RemoveModule called on module with slots"); return -1; } - state = PyThreadState_GET()->interp; + state = GET_INTERP_STATE(); if (index == 0) { Py_FatalError("PyState_RemoveModule: Module index invalid."); return -1; @@ -351,7 +353,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++) { @@ -429,7 +431,7 @@ tstate_delete_common(PyThreadState *tstate) void PyThreadState_Delete(PyThreadState *tstate) { - if (tstate == PyThreadState_GET()) + if (tstate == GET_TSTATE()) Py_FatalError("PyThreadState_Delete: tstate is still current"); #ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -443,11 +445,11 @@ PyThreadState_Delete(PyThreadState *tstate) void PyThreadState_DeleteCurrent() { - PyThreadState *tstate = PyThreadState_GET(); + 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); @@ -496,14 +498,14 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) PyThreadState * _PyThreadState_UncheckedGet(void) { - return PyThreadState_GET(); + return GET_TSTATE(); } PyThreadState * PyThreadState_Get(void) { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = GET_TSTATE(); if (tstate == NULL) Py_FatalError("PyThreadState_Get: no current thread"); @@ -514,9 +516,9 @@ PyThreadState_Get(void) PyThreadState * PyThreadState_Swap(PyThreadState *newts) { - PyThreadState *oldts = PyThreadState_GET(); + 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. @@ -545,7 +547,7 @@ PyThreadState_Swap(PyThreadState *newts) PyObject * PyThreadState_GetDict(void) { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = GET_TSTATE(); if (tstate == NULL) return NULL; @@ -569,8 +571,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 @@ -691,7 +692,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate) { /* Must be the tstate for this thread */ assert(PyGILState_GetThisThreadState()==tstate); - return tstate == PyThreadState_GET(); + return tstate == GET_TSTATE(); } /* Internal initialization/finalization functions called by @@ -783,7 +784,7 @@ PyGILState_GetThisThreadState(void) int PyGILState_Check(void) { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = GET_TSTATE(); return tstate && (tstate == PyGILState_GetThisThreadState()); } -- cgit v1.2.1 From aec4f9bc0e34e3165bc0ef73f37d8fc547d5c346 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Mon, 22 Aug 2016 18:05:56 +0300 Subject: Issue #27587: Move null pointer check earlier in _PyState_AddModule() This was found by PVS-Studio: V595 The 'def' pointer was utilized before it was verified against nullptr. Check lines: 286, 292. pystate.c 286 Initial patch by Christian Heimes. --- Python/pystate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Python/pystate.c') diff --git a/Python/pystate.c b/Python/pystate.c index 6d1c6d0a1f..24e20c3e23 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -281,14 +281,16 @@ int _PyState_AddModule(PyObject* module, struct PyModuleDef* 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 (!def) - return -1; if (!state->modules_by_index) { state->modules_by_index = PyList_New(0); if (!state->modules_by_index) -- cgit v1.2.1