thread-value: Immediately cleanup all Windows TLS values on destroy
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user