diff -r d265cae7f12e -r 289e0814baa5 Python/thread_pthread.h --- a/Python/thread_pthread.h Tue Aug 30 12:35:38 2016 +0200 +++ b/Python/thread_pthread.h Tue Aug 30 15:42:39 2016 +0200 @@ -603,46 +603,121 @@ #define Py_HAVE_NATIVE_TLS + +struct key_map { + struct key_map *next; + pthread_key_t key; + int key_id; +}; + + +static int next_key_id = 0; +static struct key_map *key_list = NULL; + + +static inline pthread_key_t * +pthread_key_from_id(int key_id) +{ + struct key_map *kl = key_list; + + while (kl != NULL) { + if (kl->key_id == key_id) { + return &(kl->key); + } + + kl = kl->next; + }; + + return NULL; +} + + int PyThread_create_key(void) { - pthread_key_t key; - int fail = pthread_key_create(&key, NULL); - if (fail) - return -1; - if (key > INT_MAX) { - /* Issue #22206: handle integer overflow */ - pthread_key_delete(key); - errno = ENOMEM; + struct key_map *km, *pkm; + km = pkm = key_list; + + while (km != NULL) { + pkm = km; + km = km->next; + } + + km = PyMem_RawCalloc(1, sizeof(struct key_map)); + if (pthread_key_create(&(km->key), NULL)) { + PyMem_RawFree(km); return -1; } - return (int)key; + + if (key_list == NULL) { + /* Create initial entry in the key_map list */ + key_list = km; + } + + km->key_id = next_key_id++; + + if (pkm != NULL) { + pkm->next = km; + } + return km->key_id; } void PyThread_delete_key(int key) { - pthread_key_delete(key); + struct key_map *km, *pkm; + pkm = km = key_list; + + while (km != NULL) { + if (km->key_id == key) { + if (km == key_list) { + key_list = km->next; + } else { + pkm->next = km->next; + } + + pthread_key_delete(km->key); + PyMem_RawFree(km); + break; + } + pkm = km; + km = km->next; + } } void PyThread_delete_key_value(int key) { - pthread_setspecific(key, NULL); + pthread_key_t *pthread_key = pthread_key_from_id(key); + + if (pthread_key != NULL) { + pthread_setspecific(*pthread_key, NULL); + } } int PyThread_set_key_value(int key, void *value) { - int fail; - fail = pthread_setspecific(key, value); - return fail ? -1 : 0; + pthread_key_t *pthread_key = pthread_key_from_id(key); + + if (pthread_key != NULL) { + if (!pthread_setspecific(*pthread_key, value)) { + return 0; + } + } + return -1; } void * PyThread_get_key_value(int key) { - return pthread_getspecific(key); + pthread_key_t *pthread_key = pthread_key_from_id(key); + + if (pthread_key != NULL) { + return pthread_getspecific(*pthread_key); + } + + return NULL; } void