When a thread exits, run the destructors for the thread's specific data.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@330 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c
index 7fba3b0..d98b730 100644
--- a/coregrind/vg_libpthread.c
+++ b/coregrind/vg_libpthread.c
@@ -279,8 +279,10 @@
__attribute__((noreturn))
void thread_exit_wrapper ( void* ret_val )
{
- int detached, res;
- CleanupEntry cu;
+ int detached, res;
+ CleanupEntry cu;
+ pthread_key_t key;
+
/* Run this thread's cleanup handlers. */
while (1) {
VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
@@ -292,7 +294,21 @@
cu.fn ( cu.arg );
}
- /* Run this thread's key finalizers. */
+ /* Run this thread's key finalizers. Really this should be run
+ PTHREAD_DESTRUCTOR_ITERATIONS times. */
+ for (key = 0; key < VG_N_THREAD_KEYS; key++) {
+ VALGRIND_MAGIC_SEQUENCE(res, (-2) /* default */,
+ VG_USERREQ__GET_KEY_D_AND_S,
+ key, &cu, 0, 0 );
+ if (res == 0) {
+ /* valid key */
+ if (cu.fn && cu.arg)
+ cu.fn /* destructor for key */
+ ( cu.arg /* specific for key for this thread */ );
+ continue;
+ }
+ assert(res == -1);
+ }
/* Decide on my final disposition. */
VALGRIND_MAGIC_SEQUENCE(detached, (-1) /* default */,