thread-value: Immediately cleanup all Windows TLS values on destroy

This commit is contained in:
Martin Willi
2014-06-04 15:53:02 +02:00
parent 9dec601f30
commit 204098a752
3 changed files with 46 additions and 14 deletions
+35 -1
View File
@@ -68,7 +68,7 @@ struct private_thread_t {
array_t *cleanup; array_t *cleanup;
/** /**
* Thread specific values for this thread, as cleanup_t * Thread specific values for this thread
*/ */
hashtable_t *tls; hashtable_t *tls;
@@ -238,12 +238,44 @@ void* thread_tls_remove(void *key)
thread = get_current_thread(); thread = get_current_thread();
old = set_leak_detective(FALSE); old = set_leak_detective(FALSE);
threads_lock->lock(threads_lock);
value = thread->tls->remove(thread->tls, key); value = thread->tls->remove(thread->tls, key);
threads_lock->unlock(threads_lock);
set_leak_detective(old); set_leak_detective(old);
return value; 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 * Thread cleanup data
*/ */
@@ -272,6 +304,7 @@ static void docleanup(private_thread_t *this)
set_leak_detective(FALSE); set_leak_detective(FALSE);
} }
threads_lock->lock(threads_lock);
enumerator = this->tls->create_enumerator(this->tls); enumerator = this->tls->create_enumerator(this->tls);
while (enumerator->enumerate(enumerator, NULL, &tls)) while (enumerator->enumerate(enumerator, NULL, &tls))
{ {
@@ -282,6 +315,7 @@ static void docleanup(private_thread_t *this)
set_leak_detective(FALSE); set_leak_detective(FALSE);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
threads_lock->unlock(threads_lock);
set_leak_detective(old); set_leak_detective(old);
} }
+10 -2
View File
@@ -73,11 +73,19 @@ void* thread_tls_get(void *key);
* Remove a thread specific value from the current thread. * Remove a thread specific value from the current thread.
* *
* @param key unique key specifying the TLS variable * @param key unique key specifying the TLS variable
* @param value value to set * @return value for key, if any
* @return old value for key, if any
*/ */
void* thread_tls_remove(void *key); 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. * Cleanup function for thread specific value.
* *
@@ -105,17 +105,7 @@ METHOD(thread_value_t, tls_get, void*,
METHOD(thread_value_t, tls_destroy, void, METHOD(thread_value_t, tls_destroy, void,
private_thread_value_t *this) private_thread_value_t *this)
{ {
entry_t *entry; thread_tls_remove_all(this);
entry = thread_tls_remove(this);
if (entry)
{
if (entry->cleanup)
{
entry->cleanup(entry->value);
}
free(entry);
}
free(this); free(this);
} }