From c40aa45d864be81bca5fff2f7f81af49955a20d2 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 26 Nov 2014 11:13:45 +0100 Subject: [PATCH] pthread: support pthread_key_delete Issue #1296 --- repos/libports/src/lib/pthread/thread.cc | 35 +++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/repos/libports/src/lib/pthread/thread.cc b/repos/libports/src/lib/pthread/thread.cc index 2bb333032..d7f0a1891 100644 --- a/repos/libports/src/lib/pthread/thread.cc +++ b/repos/libports/src/lib/pthread/thread.cc @@ -543,17 +543,16 @@ extern "C" { }; + static Lock key_list_lock; List key_list[PTHREAD_KEYS_MAX]; - int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) { - static Lock key_list_lock; - Lock_guard key_list_lock_guard(key_list_lock); - if (!key) return EINVAL; + Lock_guard key_list_lock_guard(key_list_lock); + for (int k = 0; k < PTHREAD_KEYS_MAX; k++) { /* * Find an empty key slot and insert an element for the current @@ -571,9 +570,31 @@ extern "C" { } + int pthread_key_delete(pthread_key_t key) + { + if (key < 0 || key >= PTHREAD_KEYS_MAX || !key_list[key].first()) + return EINVAL; + + Lock_guard key_list_lock_guard(key_list_lock); + + while (Key_element * element = key_list[key].first()) { + key_list[key].remove(element); + destroy(env()->heap(), element); + } + + return 0; + } + + int pthread_setspecific(pthread_key_t key, const void *value) { + if (key < 0 || key >= PTHREAD_KEYS_MAX) + return EINVAL; + void *myself = Thread_base::myself(); + + Lock_guard key_list_lock_guard(key_list_lock); + for (Key_element *key_element = key_list[key].first(); key_element; key_element = key_element->next()) if (key_element->thread_base == myself) { @@ -590,7 +611,13 @@ extern "C" { void *pthread_getspecific(pthread_key_t key) { + if (key < 0 || key >= PTHREAD_KEYS_MAX) + return nullptr; + void *myself = Thread_base::myself(); + + Lock_guard key_list_lock_guard(key_list_lock); + for (Key_element *key_element = key_list[key].first(); key_element; key_element = key_element->next()) if (key_element->thread_base == myself)