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
This commit is contained in:
Masayuki Yamamoto 2017-10-06 19:41:34 +09:00 committed by Nick Coghlan
parent b8ab9d3fc8
commit 731e189014
18 changed files with 651 additions and 108 deletions

View file

@ -589,9 +589,25 @@ _pythread_pthread_set_stacksize(size_t size)
#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
/* Thread Local Storage (TLS) API
This API is DEPRECATED since Python 3.7. See PEP 539 for details.
*/
/* Issue #25658: On platforms where native TLS key is defined in a way that
cannot be safely cast to int, PyThread_create_key returns immediately a
failure status and other TLS functions all are no-ops. This indicates
clearly that the old API is not supported on platforms where it cannot be
used reliably, and that no effort will be made to add such support.
Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
removing this API.
*/
int
PyThread_create_key(void)
{
#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
pthread_key_t key;
int fail = pthread_key_create(&key, NULL);
if (fail)
@ -603,34 +619,102 @@ PyThread_create_key(void)
return -1;
}
return (int)key;
#else
return -1; /* never return valid key value. */
#endif
}
void
PyThread_delete_key(int key)
{
#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
pthread_key_delete(key);
#endif
}
void
PyThread_delete_key_value(int key)
{
#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
pthread_setspecific(key, NULL);
#endif
}
int
PyThread_set_key_value(int key, void *value)
{
int fail;
fail = pthread_setspecific(key, value);
#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
int fail = pthread_setspecific(key, value);
return fail ? -1 : 0;
#else
return -1;
#endif
}
void *
PyThread_get_key_value(int key)
{
#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
return pthread_getspecific(key);
#else
return NULL;
#endif
}
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;
}
int fail = pthread_key_create(&(key->_key), NULL);
if (fail) {
return -1;
}
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;
}
pthread_key_delete(key->_key);
/* pthread has not provided the defined invalid value for the key. */
key->_is_initialized = 0;
}
int
PyThread_tss_set(Py_tss_t *key, void *value)
{
assert(key != NULL);
int fail = pthread_setspecific(key->_key, value);
return fail ? -1 : 0;
}
void *
PyThread_tss_get(Py_tss_t *key)
{
assert(key != NULL);
return pthread_getspecific(key->_key);
}