summaryrefslogtreecommitdiff
path: root/Python/pystate.c
diff options
context:
space:
mode:
authorMasayuki Yamamoto <ma3yuki.8mamo10@gmail.com>2017-10-06 19:41:34 +0900
committerNick Coghlan <ncoghlan@gmail.com>2017-10-06 20:41:34 +1000
commit731e18901484c75b60167a06a0ba0719a6d4827d (patch)
treefc9b8afc6eb8453729c130a146b838228ab103c6 /Python/pystate.c
parentb8ab9d3fc816f85f4d6dbef12b7414e6dc10e4dd (diff)
downloadcpython-git-731e18901484c75b60167a06a0ba0719a6d4827d.tar.gz
bpo-25658: Implement PEP 539 for Thread Specific Storage (TSS) API (GH-1362)
See PEP 539 for details. Highlights of changes: - Add Thread Specific Storage (TSS) API - Document the Thread Local Storage (TLS) API as deprecated - Update code that used TLS API to use TSS API
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c71
1 files changed, 38 insertions, 33 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 53c1236145..3feae346d4 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -46,7 +46,12 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
_PyEval_Initialize(&runtime->ceval);
runtime->gilstate.check_enabled = 1;
- runtime->gilstate.autoTLSkey = -1;
+ /* A TSS key must be initialized with Py_tss_NEEDS_INIT
+ in accordance with the specification. */
+ {
+ Py_tss_t initial = Py_tss_NEEDS_INIT;
+ runtime->gilstate.autoTSSkey = initial;
+ }
runtime->interpreters.mutex = PyThread_allocate_lock();
if (runtime->interpreters.mutex == NULL)
@@ -485,9 +490,9 @@ PyThreadState_Delete(PyThreadState *tstate)
if (tstate == GET_TSTATE())
Py_FatalError("PyThreadState_Delete: tstate is still current");
if (_PyRuntime.gilstate.autoInterpreterState &&
- PyThread_get_key_value(_PyRuntime.gilstate.autoTLSkey) == tstate)
+ PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate)
{
- PyThread_delete_key_value(_PyRuntime.gilstate.autoTLSkey);
+ PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL);
}
tstate_delete_common(tstate);
}
@@ -502,9 +507,9 @@ PyThreadState_DeleteCurrent()
"PyThreadState_DeleteCurrent: no current tstate");
tstate_delete_common(tstate);
if (_PyRuntime.gilstate.autoInterpreterState &&
- PyThread_get_key_value(_PyRuntime.gilstate.autoTLSkey) == tstate)
+ PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate)
{
- PyThread_delete_key_value(_PyRuntime.gilstate.autoTLSkey);
+ PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL);
}
SET_TSTATE(NULL);
PyEval_ReleaseLock();
@@ -761,11 +766,11 @@ void
_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
{
assert(i && t); /* must init with valid states */
- _PyRuntime.gilstate.autoTLSkey = PyThread_create_key();
- if (_PyRuntime.gilstate.autoTLSkey == -1)
- Py_FatalError("Could not allocate TLS entry");
+ if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {
+ Py_FatalError("Could not allocate TSS entry");
+ }
_PyRuntime.gilstate.autoInterpreterState = i;
- assert(PyThread_get_key_value(_PyRuntime.gilstate.autoTLSkey) == NULL);
+ assert(PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL);
assert(t->gilstate_counter == 0);
_PyGILState_NoteThreadState(t);
@@ -780,14 +785,13 @@ _PyGILState_GetInterpreterStateUnsafe(void)
void
_PyGILState_Fini(void)
{
- PyThread_delete_key(_PyRuntime.gilstate.autoTLSkey);
- _PyRuntime.gilstate.autoTLSkey = -1;
+ PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
_PyRuntime.gilstate.autoInterpreterState = NULL;
}
-/* Reset the TLS key - called by PyOS_AfterFork_Child().
+/* Reset the TSS key - called by PyOS_AfterFork_Child().
* This should not be necessary, but some - buggy - pthread implementations
- * don't reset TLS upon fork(), see issue #10517.
+ * don't reset TSS upon fork(), see issue #10517.
*/
void
_PyGILState_Reinit(void)
@@ -796,15 +800,18 @@ _PyGILState_Reinit(void)
if (_PyRuntime.interpreters.mutex == NULL)
Py_FatalError("Can't initialize threads for interpreter");
PyThreadState *tstate = PyGILState_GetThisThreadState();
- PyThread_delete_key(_PyRuntime.gilstate.autoTLSkey);
- if ((_PyRuntime.gilstate.autoTLSkey = PyThread_create_key()) == -1)
- Py_FatalError("Could not allocate TLS entry");
+ PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey);
+ if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) {
+ Py_FatalError("Could not allocate TSS entry");
+ }
/* If the thread had an associated auto thread state, reassociate it with
* the new key. */
- if (tstate && PyThread_set_key_value(_PyRuntime.gilstate.autoTLSkey,
- (void *)tstate) < 0)
- Py_FatalError("Couldn't create autoTLSkey mapping");
+ if (tstate &&
+ PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate) != 0)
+ {
+ Py_FatalError("Couldn't create autoTSSkey mapping");
+ }
}
/* When a thread state is created for a thread by some mechanism other than
@@ -815,13 +822,13 @@ _PyGILState_Reinit(void)
static void
_PyGILState_NoteThreadState(PyThreadState* tstate)
{
- /* If autoTLSkey isn't initialized, this must be the very first
+ /* If autoTSSkey isn't initialized, this must be the very first
threadstate created in Py_Initialize(). Don't do anything for now
(we'll be back here when _PyGILState_Init is called). */
if (!_PyRuntime.gilstate.autoInterpreterState)
return;
- /* Stick the thread state for this thread in thread local storage.
+ /* Stick the thread state for this thread in thread specific storage.
The only situation where you can legitimately have more than one
thread state for an OS level thread is when there are multiple
@@ -833,12 +840,11 @@ _PyGILState_NoteThreadState(PyThreadState* tstate)
The first thread state created for that given OS level thread will
"win", which seems reasonable behaviour.
*/
- if (PyThread_get_key_value(_PyRuntime.gilstate.autoTLSkey) == NULL) {
- if ((PyThread_set_key_value(_PyRuntime.gilstate.autoTLSkey,
- (void *)tstate)
- ) < 0)
+ if (PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == NULL) {
+ if ((PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, (void *)tstate)
+ ) != 0)
{
- Py_FatalError("Couldn't create autoTLSkey mapping");
+ Py_FatalError("Couldn't create autoTSSkey mapping");
}
}
@@ -852,8 +858,7 @@ PyGILState_GetThisThreadState(void)
{
if (_PyRuntime.gilstate.autoInterpreterState == NULL)
return NULL;
- return (PyThreadState *)PyThread_get_key_value(
- _PyRuntime.gilstate.autoTLSkey);
+ return (PyThreadState *)PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey);
}
int
@@ -864,8 +869,9 @@ PyGILState_Check(void)
if (!_PyGILState_check_enabled)
return 1;
- if (_PyRuntime.gilstate.autoTLSkey == -1)
+ if (!PyThread_tss_is_created(&_PyRuntime.gilstate.autoTSSkey)) {
return 1;
+ }
tstate = GET_TSTATE();
if (tstate == NULL)
@@ -886,8 +892,7 @@ PyGILState_Ensure(void)
*/
/* Py_Initialize() hasn't been called! */
assert(_PyRuntime.gilstate.autoInterpreterState);
- tcur = (PyThreadState *)PyThread_get_key_value(
- _PyRuntime.gilstate.autoTLSkey);
+ tcur = (PyThreadState *)PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey);
if (tcur == NULL) {
/* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
called from a new thread for the first time, we need the create the
@@ -919,8 +924,8 @@ PyGILState_Ensure(void)
void
PyGILState_Release(PyGILState_STATE oldstate)
{
- PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
- _PyRuntime.gilstate.autoTLSkey);
+ PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(
+ &_PyRuntime.gilstate.autoTSSkey);
if (tcur == NULL)
Py_FatalError("auto-releasing thread-state, "
"but no thread-state for this thread");