about summary refs log tree commit diff
path: root/linuxthreads
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-02-08 10:05:09 +0000
committerJakub Jelinek <jakub@redhat.com>2005-02-08 10:05:09 +0000
commitd585b66fa4d11059948f466c9080a6826932358d (patch)
tree8b06692920852c297635b46a7d616c3066f95fac /linuxthreads
parente7cbcee4982d8caa809a91c9cfef5fda67445f0a (diff)
downloadglibc-d585b66fa4d11059948f466c9080a6826932358d.tar.gz
glibc-d585b66fa4d11059948f466c9080a6826932358d.tar.xz
glibc-d585b66fa4d11059948f466c9080a6826932358d.zip
Updated to fedora-glibc-20050208T0948 cvs/fedora-glibc-2_3_4-6
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog23
-rw-r--r--linuxthreads/Makefile4
-rw-r--r--linuxthreads/pthread.c3
-rw-r--r--linuxthreads/specific.c14
-rw-r--r--linuxthreads/sysdeps/alpha/tls.h9
-rw-r--r--linuxthreads/sysdeps/i386/tls.h9
-rw-r--r--linuxthreads/sysdeps/ia64/tls.h9
-rw-r--r--linuxthreads/sysdeps/powerpc/tls.h15
-rw-r--r--linuxthreads/sysdeps/s390/tls.h9
-rw-r--r--linuxthreads/sysdeps/sh/tls.h9
-rw-r--r--linuxthreads/sysdeps/sparc/tls.h9
-rw-r--r--linuxthreads/sysdeps/x86_64/tls.h9
-rw-r--r--linuxthreads/tst-tsd1.c118
13 files changed, 214 insertions, 26 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index ff1b7fea93..329f2d8b12 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,26 @@
+2005-02-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* specific.c (pthread_key_delete): If pthread_create has not been
+	called yet, clear p_specific for the current thread.
+	* Makefile (tests): Add tst-tsd1.
+	* tst-tsd1.c: New test.
+
+2005-01-08  Andreas Jaeger  <aj@suse.de>
+
+	* pthread.c (init_one_static_tls): Adjust initialization of DTV
+	entry for static tls deallocation fix.
+
+	* sysdeps/alpha/tls.h (dtv_t): Change pointer type to be struct which
+	also contains information whether the memory pointed to is static
+	TLS or not, include <stdbool.h>.
+	* sysdeps/i386/tls.h: Likewise.
+	* sysdeps/ia64/tls.h: Likewise.
+	* sysdeps/powerpc/tls.h: Likewise.
+	* sysdeps/s390/tls.h: Likewise.
+	* sysdeps/sh/tls.h: Likewise.
+	* sysdeps/sparc/tls.h: Likewise.
+	* sysdeps/x86_64/tls.h: Likewise.
+
 2004-12-21  Jakub Jelinek  <jakub@redhat.com>
 
 	* Makefile (tests): Add tst-align.
diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile
index d9bf476c7e..c2b548b38b 100644
--- a/linuxthreads/Makefile
+++ b/linuxthreads/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1996-2003, 2004, 2005 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -111,7 +111,7 @@ tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \
 	ex17 ex18 tst-cancel tst-context bug-sleep \
 	tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
 	tst-cancel6 tst-cancel7 tst-cancel8 tst-popen tst-popen2 tst-attr1 \
-	tst-stack1 tst-align
+	tst-stack1 tst-align tst-tsd1
 test-srcs = tst-signal
 # These tests are linked with libc before libpthread
 tests-reverse += tst-cancel5
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 24f0eb02b0..39863f2b54 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -482,7 +482,8 @@ init_one_static_tls (pthread_descr descr, struct link_map *map)
 # endif
 
   /* Fill in the DTV slot so that a later LD/GD access will find it.  */
-  dtv[map->l_tls_modid].pointer = dest;
+  dtv[map->l_tls_modid].pointer.val = dest;
+  dtv[map->l_tls_modid].pointer.is_static = true;
 
   /* Initialize the memory.  */
   memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
diff --git a/linuxthreads/specific.c b/linuxthreads/specific.c
index f54fabaeb9..92eec3d99a 100644
--- a/linuxthreads/specific.c
+++ b/linuxthreads/specific.c
@@ -104,15 +104,16 @@ int pthread_key_delete(pthread_key_t key)
      that if the key is reallocated later by pthread_key_create, its
      associated values will be NULL in all threads.
 
-     Do nothing if no threads have been created yet.  */
+     If no threads have been created yet, clear it just in the
+     current thread.  */
 
+  struct pthread_key_delete_helper_args args;
+  args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
+  args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
   if (__pthread_manager_request != -1)
     {
-      struct pthread_key_delete_helper_args args;
       struct pthread_request request;
 
-      args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
-      args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
       args.self = 0;
 
       request.req_thread = self;
@@ -124,6 +125,11 @@ int pthread_key_delete(pthread_key_t key)
 					  (char *) &request, sizeof(request)));
       suspend(self);
     }
+  else
+    {
+      if (self->p_specific[args.idx1st] != NULL)
+	self->p_specific[args.idx1st][args.idx2nd] = NULL;
+    }
 
   pthread_mutex_unlock(&pthread_keys_mutex);
   return 0;
diff --git a/linuxthreads/sysdeps/alpha/tls.h b/linuxthreads/sysdeps/alpha/tls.h
index 9e15318b79..1eabf5b890 100644
--- a/linuxthreads/sysdeps/alpha/tls.h
+++ b/linuxthreads/sysdeps/alpha/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/Alpha version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -23,13 +23,18 @@
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
diff --git a/linuxthreads/sysdeps/i386/tls.h b/linuxthreads/sysdeps/i386/tls.h
index d296340ad8..f5d555baec 100644
--- a/linuxthreads/sysdeps/i386/tls.h
+++ b/linuxthreads/sysdeps/i386/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  linuxthreads/i386 version.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -24,6 +24,7 @@
 # include <pt-machine.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
@@ -31,7 +32,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
diff --git a/linuxthreads/sysdeps/ia64/tls.h b/linuxthreads/sysdeps/ia64/tls.h
index 6bdf819d8d..fe8fcd15f8 100644
--- a/linuxthreads/sysdeps/ia64/tls.h
+++ b/linuxthreads/sysdeps/ia64/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/IA-64 version.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -24,13 +24,18 @@
 
 # include <dl-sysdep.h>
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
diff --git a/linuxthreads/sysdeps/powerpc/tls.h b/linuxthreads/sysdeps/powerpc/tls.h
index fda953976e..35472081d6 100644
--- a/linuxthreads/sysdeps/powerpc/tls.h
+++ b/linuxthreads/sysdeps/powerpc/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/PPC version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -23,13 +23,18 @@
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
@@ -107,9 +112,9 @@ typedef struct
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
    operation can cause a failure 'errno' must not be touched.
-   
-   The global register variable is declared in pt-machine.h with the 
-   wrong type, so we need some extra casts to get the desired result.  
+
+   The global register variable is declared in pt-machine.h with the
+   wrong type, so we need some extra casts to get the desired result.
    This avoids a lvalue cast that gcc-3.4 does not like.  */
 # define TLS_INIT_TP(TCBP, SECONDCALL) \
     (__thread_self = (struct _pthread_descr_struct *) \
diff --git a/linuxthreads/sysdeps/s390/tls.h b/linuxthreads/sysdeps/s390/tls.h
index f420195bd2..00a4df9382 100644
--- a/linuxthreads/sysdeps/s390/tls.h
+++ b/linuxthreads/sysdeps/s390/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/s390 version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -23,13 +23,18 @@
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 typedef struct
diff --git a/linuxthreads/sysdeps/sh/tls.h b/linuxthreads/sysdeps/sh/tls.h
index bc9d44fa85..fbc6f01151 100644
--- a/linuxthreads/sysdeps/sh/tls.h
+++ b/linuxthreads/sysdeps/sh/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  linuxthreads/SH version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -24,6 +24,7 @@
 # include <pt-machine.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
@@ -31,7 +32,11 @@
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
diff --git a/linuxthreads/sysdeps/sparc/tls.h b/linuxthreads/sysdeps/sparc/tls.h
index 5053824058..3e550fa7c7 100644
--- a/linuxthreads/sysdeps/sparc/tls.h
+++ b/linuxthreads/sysdeps/sparc/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/sparc version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -23,13 +23,18 @@
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 typedef struct
diff --git a/linuxthreads/sysdeps/x86_64/tls.h b/linuxthreads/sysdeps/x86_64/tls.h
index d979bbd896..67d80b28d9 100644
--- a/linuxthreads/sysdeps/x86_64/tls.h
+++ b/linuxthreads/sysdeps/x86_64/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/x86-64 version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -23,13 +23,18 @@
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
diff --git a/linuxthreads/tst-tsd1.c b/linuxthreads/tst-tsd1.c
new file mode 100644
index 0000000000..ba7973f1c4
--- /dev/null
+++ b/linuxthreads/tst-tsd1.c
@@ -0,0 +1,118 @@
+/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+
+
+static int
+do_test (void)
+{
+  pthread_key_t key1;
+  pthread_key_t key2;
+  void *value;
+  int result = 0;
+  int err;
+
+  err = pthread_key_create (&key1, NULL);
+  if (err != 0)
+    {
+      printf ("1st key_create failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  /* Initial value must be NULL.  */
+  value = pthread_getspecific (key1);
+  if (value != NULL)
+    {
+      puts ("1st getspecific != NULL");
+      result = 1;
+    }
+
+  err = pthread_setspecific (key1, (void *) -2l);
+  if (err != 0)
+    {
+      printf ("1st setspecific failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  value = pthread_getspecific (key1);
+  if (value == NULL)
+    {
+      puts ("2nd getspecific == NULL\n");
+      result = 1;
+    }
+  else if (value != (void *) -2l)
+    {
+      puts ("2nd getspecific != -2l\n");
+      result = 1;
+    }
+
+  err = pthread_setspecific (key1, (void *) -3l);
+  if (err != 0)
+    {
+      printf ("2nd setspecific failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  value = pthread_getspecific (key1);
+  if (value == NULL)
+    {
+      puts ("3rd getspecific == NULL\n");
+      result = 1;
+    }
+  else if (value != (void *) -3l)
+    {
+      puts ("3rd getspecific != -2l\n");
+      result = 1;
+    }
+
+  err = pthread_key_delete (key1);
+  if (err != 0)
+    {
+      printf ("key_delete failed: %s\n", strerror (err));
+      result = 1;
+    }
+
+
+  err = pthread_key_create (&key2, NULL);
+  if (err != 0)
+    {
+      printf ("2nd key_create failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  if (key1 != key2)
+    puts ("key1 != key2; no more tests performed");
+  else
+    {
+      value = pthread_getspecific (key2);
+      if (value != NULL)
+	{
+	  puts ("4th getspecific != NULL");
+	  result = 1;
+	}
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"