[BZ #4938]
authorUlrich Drepper <drepper@redhat.com>
Tue, 21 Aug 2007 23:55:36 +0000 (23:55 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 21 Aug 2007 23:55:36 +0000 (23:55 +0000)
2007-08-21  Ulrich Drepper  <drepper@redhat.com>
[BZ #4938]
* allocatestack.c (__reclaim_stacks): Clear the TSD in the
reclaimed stack if necessary.
* Makefile (tests): Add tst-tsd6.
* tst-tsd6.c: New file.

nptl/ChangeLog
nptl/Makefile
nptl/allocatestack.c
nptl/tst-tsd6.c [new file with mode: 0644]

index 96b49a8..60e770b 100644 (file)
@@ -1,3 +1,11 @@
+2007-08-21  Ulrich Drepper  <drepper@redhat.com>
+
+       [BZ #4938]
+       * allocatestack.c (__reclaim_stacks): Clear the TSD in the
+       reclaimed stack if necessary.
+       * Makefile (tests): Add tst-tsd6.
+       * tst-tsd6.c: New file.
+
 2007-08-21  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_robust_dead):
index a9eac89..f239846 100644 (file)
@@ -227,7 +227,7 @@ tests = tst-typesizes \
        tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \
        tst-detach1 \
        tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
-       tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 \
+       tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \
        tst-tls1 tst-tls2 \
        tst-fork1 tst-fork2 tst-fork3 tst-fork4 \
        tst-atfork1 \
index 02a84f4..c894e96 100644 (file)
@@ -794,6 +794,26 @@ __reclaim_stacks (void)
 
          /* Account for the size of the stack.  */
          stack_cache_actsize += curp->stackblock_size;
+
+         if (curp->specific_used)
+           {
+             /* Clear the thread-specific data.  */
+             memset (curp->specific_1stblock, '\0',
+                     sizeof (curp->specific_1stblock));
+
+             curp->specific_used = false;
+
+             for (size_t cnt = 1; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
+               if (curp->specific[cnt] != NULL)
+                 {
+                   memset (curp->specific[cnt], '\0',
+                           sizeof (curp->specific_1stblock));
+
+                   /* We have allocated the block which we do not
+                      free here so re-set the bit.  */
+                   curp->specific_used = true;
+                 }
+           }
        }
     }
 
diff --git a/nptl/tst-tsd6.c b/nptl/tst-tsd6.c
new file mode 100644 (file)
index 0000000..debb1dd
--- /dev/null
@@ -0,0 +1,89 @@
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#define NKEYS 100
+static pthread_key_t keys[NKEYS];
+static pthread_barrier_t b;
+
+
+static void *
+tf (void *arg)
+{
+  void *res = NULL;
+  for (int i = 0; i < NKEYS; ++i)
+    {
+      void *p = pthread_getspecific (keys[i]);
+      pthread_setspecific (keys[i], (void *) 7);
+      if (p != NULL)
+       res = p;
+    }
+  if (arg != NULL)
+    {
+      pthread_barrier_wait (arg);
+      pthread_barrier_wait (arg);
+    }
+  return res;
+}
+
+
+static int
+do_test (void)
+{
+  pthread_barrier_init (&b, NULL, 2);
+
+  for (int i = 0; i < NKEYS; ++i)
+    if (pthread_key_create (&keys[i], NULL) != 0)
+      {
+       puts ("cannot create keys");
+       return 1;
+      }
+
+  pthread_t th;
+  if (pthread_create (&th, NULL, tf, &b) != 0)
+    {
+      puts ("cannot create thread in parent");
+      return 1;
+    }
+
+  pthread_barrier_wait (&b);
+
+  pid_t pid = fork ();
+  if (pid == 0)
+    {
+      if (pthread_create (&th, NULL, tf, NULL) != 0)
+       {
+         puts ("cannot create thread in child");
+         exit (1);
+       }
+
+      void *res;
+      pthread_join (th, &res);
+
+      exit (res != NULL);
+    }
+  else if (pid == -1)
+    {
+      puts ("cannot create child process");
+      return 1;
+    }
+
+  int s;
+  if (TEMP_FAILURE_RETRY (waitpid (pid, &s, 0)) != pid)
+    {
+      puts ("failing to wait for child process");
+      return 1;
+    }
+
+  pthread_barrier_wait (&b);
+  pthread_join (th, NULL);
+
+  return !WIFEXITED (s) ? 2 : WEXITSTATUS (s);
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"