diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/threading/windows/thread.c | 36 | ||||
-rw-r--r-- | src/libstrongswan/threading/windows/thread.h | 12 | ||||
-rw-r--r-- | src/libstrongswan/threading/windows/thread_value.c | 12 |
3 files changed, 46 insertions, 14 deletions
diff --git a/src/libstrongswan/threading/windows/thread.c b/src/libstrongswan/threading/windows/thread.c index 5fa68bb91..35d56c47d 100644 --- a/src/libstrongswan/threading/windows/thread.c +++ b/src/libstrongswan/threading/windows/thread.c @@ -68,7 +68,7 @@ struct private_thread_t { array_t *cleanup; /** - * Thread specific values for this thread, as cleanup_t + * Thread specific values for this thread */ hashtable_t *tls; @@ -238,13 +238,45 @@ void* thread_tls_remove(void *key) thread = get_current_thread(); old = set_leak_detective(FALSE); + threads_lock->lock(threads_lock); value = thread->tls->remove(thread->tls, key); + threads_lock->unlock(threads_lock); set_leak_detective(old); return value; } /** + * See header. + */ +void thread_tls_remove_all(void *key) +{ + private_thread_t *thread; + enumerator_t *enumerator; + void *value; + bool old; + + old = set_leak_detective(FALSE); + threads_lock->lock(threads_lock); + + enumerator = threads->create_enumerator(threads); + while (enumerator->enumerate(enumerator, NULL, &thread)) + { + value = thread->tls->remove(thread->tls, key); + if (value) + { + set_leak_detective(old); + thread_tls_cleanup(value); + set_leak_detective(FALSE); + } + } + enumerator->destroy(enumerator); + + threads_lock->unlock(threads_lock); + set_leak_detective(old); +} + +/** * Thread cleanup data */ typedef struct { @@ -272,6 +304,7 @@ static void docleanup(private_thread_t *this) set_leak_detective(FALSE); } + threads_lock->lock(threads_lock); enumerator = this->tls->create_enumerator(this->tls); while (enumerator->enumerate(enumerator, NULL, &tls)) { @@ -282,6 +315,7 @@ static void docleanup(private_thread_t *this) set_leak_detective(FALSE); } enumerator->destroy(enumerator); + threads_lock->unlock(threads_lock); set_leak_detective(old); } diff --git a/src/libstrongswan/threading/windows/thread.h b/src/libstrongswan/threading/windows/thread.h index e393d183c..571171702 100644 --- a/src/libstrongswan/threading/windows/thread.h +++ b/src/libstrongswan/threading/windows/thread.h @@ -73,12 +73,20 @@ void* thread_tls_get(void *key); * Remove a thread specific value from the current thread. * * @param key unique key specifying the TLS variable - * @param value value to set - * @return old value for key, if any + * @return value for key, if any */ void* thread_tls_remove(void *key); /** + * Remove a thread specific value from all threads. + * + * For each found TLS value thread_tls_cleanup() is invoked. + * + * @param key unique key specifying the TLS variable + */ +void thread_tls_remove_all(void *key); + +/** * Cleanup function for thread specific value. * * This is called whenever a thread exits to clean up thread specific data. diff --git a/src/libstrongswan/threading/windows/thread_value.c b/src/libstrongswan/threading/windows/thread_value.c index 8ba127fd4..da79d7b44 100644 --- a/src/libstrongswan/threading/windows/thread_value.c +++ b/src/libstrongswan/threading/windows/thread_value.c @@ -105,17 +105,7 @@ METHOD(thread_value_t, tls_get, void*, METHOD(thread_value_t, tls_destroy, void, private_thread_value_t *this) { - entry_t *entry; - - entry = thread_tls_remove(this); - if (entry) - { - if (entry->cleanup) - { - entry->cleanup(entry->value); - } - free(entry); - } + thread_tls_remove_all(this); free(this); } |