aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/threading/windows/thread.c36
-rw-r--r--src/libstrongswan/threading/windows/thread.h12
-rw-r--r--src/libstrongswan/threading/windows/thread_value.c12
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);
}