summaryrefslogtreecommitdiff
path: root/Python/thread_nt.h
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/thread_nt.h
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/thread_nt.h')
-rw-r--r--Python/thread_nt.h82
1 files changed, 74 insertions, 8 deletions
diff --git a/Python/thread_nt.h b/Python/thread_nt.h
index 2f3a71b86a..bae8bcc356 100644
--- a/Python/thread_nt.h
+++ b/Python/thread_nt.h
@@ -349,10 +349,15 @@ _pythread_nt_set_stacksize(size_t size)
#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
+/* Thread Local Storage (TLS) API
+
+ This API is DEPRECATED since Python 3.7. See PEP 539 for details.
+*/
+
int
PyThread_create_key(void)
{
- DWORD result= TlsAlloc();
+ DWORD result = TlsAlloc();
if (result == TLS_OUT_OF_INDEXES)
return -1;
return (int)result;
@@ -367,12 +372,8 @@ PyThread_delete_key(int key)
int
PyThread_set_key_value(int key, void *value)
{
- BOOL ok;
-
- ok = TlsSetValue(key, value);
- if (!ok)
- return -1;
- return 0;
+ BOOL ok = TlsSetValue(key, value);
+ return ok ? 0 : -1;
}
void *
@@ -399,9 +400,74 @@ PyThread_delete_key_value(int key)
TlsSetValue(key, NULL);
}
+
/* reinitialization of TLS is not necessary after fork when using
* the native TLS functions. And forking isn't supported on Windows either.
*/
void
PyThread_ReInitTLS(void)
-{}
+{
+}
+
+
+/* Thread Specific Storage (TSS) API
+
+ Platform-specific components of TSS API implementation.
+*/
+
+int
+PyThread_tss_create(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* If the key has been created, function is silently skipped. */
+ if (key->_is_initialized) {
+ return 0;
+ }
+
+ DWORD result = TlsAlloc();
+ if (result == TLS_OUT_OF_INDEXES) {
+ return -1;
+ }
+ /* In Windows, platform-specific key type is DWORD. */
+ key->_key = result;
+ key->_is_initialized = 1;
+ return 0;
+}
+
+void
+PyThread_tss_delete(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* If the key has not been created, function is silently skipped. */
+ if (!key->_is_initialized) {
+ return;
+ }
+
+ TlsFree(key->_key);
+ key->_key = TLS_OUT_OF_INDEXES;
+ key->_is_initialized = 0;
+}
+
+int
+PyThread_tss_set(Py_tss_t *key, void *value)
+{
+ assert(key != NULL);
+ BOOL ok = TlsSetValue(key->_key, value);
+ return ok ? 0 : -1;
+}
+
+void *
+PyThread_tss_get(Py_tss_t *key)
+{
+ assert(key != NULL);
+ /* because TSS is used in the Py_END_ALLOW_THREAD macro,
+ * it is necessary to preserve the windows error state, because
+ * it is assumed to be preserved across the call to the macro.
+ * Ideally, the macro should be fixed, but it is simpler to
+ * do it here.
+ */
+ DWORD error = GetLastError();
+ void *result = TlsGetValue(key->_key);
+ SetLastError(error);
+ return result;
+}