This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.17-244-gba384f6


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  ba384f6ed9275f3966505f2375b56d169e3dc588 (commit)
      from  ffaa74cf68a370e232279a9a9b0a02ade287cc99 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ba384f6ed9275f3966505f2375b56d169e3dc588

commit ba384f6ed9275f3966505f2375b56d169e3dc588
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Mon Feb 18 19:08:21 2013 +0530

    C++11 thread_local destructors support
    
    This feature is specifically for the C++ compiler to offload calling
    thread_local object destructors on thread program exit, to glibc.
    This is to overcome the possible complication of destructors of
    thread_local objects getting called after the DSO in which they're
    defined is unloaded by the dynamic linker.  The DSO is marked as
    'unloadable' if it has a constructed thread_local object and marked as
    'unloadable' again when all the constructed thread_local objects
    defined in it are destroyed.

diff --git a/ChangeLog b/ChangeLog
index 20a7aa1..44ab1f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,38 @@
 2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
+	* Versions.def: Add GLIBC_2.18.
+	* include/link.h (struct link_map): New member l_tls_dtor_count.
+	* include/stdlib.h (__cxa_thread_atexit_impl): Declare.
+	(__call_tls_dtors): Likewise.
+	* sysdeps/unix/sysv/linux/i386/nptl/libc.abilist: Add
+	__cxa_thread_atexit_impl.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/sh/nptl/libc.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/nptl/libc.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/nptl/libc.abilist:
+	Likewise.
+	* stdlib/Makefile (routines): Add __cxa_thread_atexit_impl.
+	(tests): Add test case tst-tls-atexit.
+	(modules-names): Add shared library for tst-tls-atexit.
+	* stdlib/Versions (GLIBC_2.17): Add __cxa_thread_atexit_impl.
+	(GLIBC_PRIVATE): Add __call_tls_dtors.
+	* stdlib/cxa_thread_atexit_impl.c: New file with helper function
+	for libstdc++.
+	* stdlib/exit.c (__run_exit_handlers): Call __call_tls_dtors.
+	* stdlib/tst-tls-atexit.c: New test case.
+	* stdlib/tst-tls-atexit-lib.c: New test case.
+
 	* misc/tst-pselect.c: Include stdlib.h for declaration of exit.
 	* nptl/sysdeps/pthread/tst-timer.c: Likewise.
 	* nptl/tst-barrier4.c: Likewise.
diff --git a/Versions.def b/Versions.def
index 3c9e0ae..8651992 100644
--- a/Versions.def
+++ b/Versions.def
@@ -34,6 +34,7 @@ libc {
   GLIBC_2.15
   GLIBC_2.16
   GLIBC_2.17
+  GLIBC_2.18
   HURD_CTHREADS_0.3
 %ifdef EXPORT_UNWIND_FIND_FDE
   GCC_3.0
diff --git a/include/link.h b/include/link.h
index 230e95d..7dc3cd1 100644
--- a/include/link.h
+++ b/include/link.h
@@ -302,6 +302,9 @@ struct link_map
     /* Index of the module in the dtv array.  */
     size_t l_tls_modid;
 
+    /* Number of thread_local objects constructed by this DSO.  */
+    size_t l_tls_dtor_count;
+
     /* Information used to change permission after the relocations are
        done.  */
     ElfW(Addr) l_relro_addr;
diff --git a/include/stdlib.h b/include/stdlib.h
index 2e53664..db1812d 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -100,6 +100,11 @@ extern int __cxa_atexit (void (*func) (void *), void *arg, void *d);
 extern int __cxa_atexit_internal (void (*func) (void *), void *arg, void *d)
      attribute_hidden;
 
+extern int __cxa_thread_atexit_impl (void (*func) (void *), void *arg,
+				     void *d);
+extern void __call_tls_dtors (void);
+libc_hidden_proto (__call_tls_dtors);
+
 extern void __cxa_finalize (void *d);
 
 extern int __posix_memalign (void **memptr, size_t alignment, size_t size);
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 4fe0755..c6f2fdd 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -311,6 +311,9 @@ start_thread (void *arg)
 #endif
     }
 
+  /* Call destructors for the thread_local TLS variables.  */
+  __call_tls_dtors ();
+
   /* Run the destructor for the thread-local data.  */
   __nptl_deallocate_tsd ();
 
diff --git a/ports/ChangeLog.alpha b/ports/ChangeLog.alpha
index 991c36a..0ac8add 100644
--- a/ports/ChangeLog.alpha
+++ b/ports/ChangeLog.alpha
@@ -1,3 +1,8 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/nptl/libc.abilist: Add
+	__cxa_thread_atexit_impl.
+
 2013-02-14  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #13550]
diff --git a/ports/ChangeLog.arm b/ports/ChangeLog.arm
index 2596b8d..3a5880b 100644
--- a/ports/ChangeLog.arm
+++ b/ports/ChangeLog.arm
@@ -1,3 +1,8 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/arm/nptl/libc.abilist: Add
+	__cxa_thread_atexit_impl.
+
 2013-02-13  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #13550]
diff --git a/ports/ChangeLog.ia64 b/ports/ChangeLog.ia64
index 26d99f7..d9fda45 100644
--- a/ports/ChangeLog.ia64
+++ b/ports/ChangeLog.ia64
@@ -1,3 +1,8 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist: Add
+	__cxa_thread_atexit_impl.
+
 2013-02-08  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #13550]
diff --git a/ports/ChangeLog.m68k b/ports/ChangeLog.m68k
index dfbe0df..e7cb81e 100644
--- a/ports/ChangeLog.m68k
+++ b/ports/ChangeLog.m68k
@@ -1,3 +1,10 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libc.abilist: Add
+	__cxa_thread_atexit_impl.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libc.abilist:
+	Likewise.
+
 2013-02-08  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* sysdeps/unix/sysv/linux/m68k/kernel-features.h
diff --git a/ports/ChangeLog.mips b/ports/ChangeLog.mips
index b91a1a8..de967c6 100644
--- a/ports/ChangeLog.mips
+++ b/ports/ChangeLog.mips
@@ -1,3 +1,12 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist: Add
+	__cxa_thread_atexit_impl.
+	* sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libc.abilist:
+	Likewise.
+
 2013-02-13  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #13550]
diff --git a/ports/ChangeLog.powerpc b/ports/ChangeLog.powerpc
index ecac527..c66dc07 100644
--- a/ports/ChangeLog.powerpc
+++ b/ports/ChangeLog.powerpc
@@ -1,3 +1,10 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist:
+	Add __cxa_thread_atexit_impl.
+	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libc.abilist:
+	Likewise.
+
 2013-02-14  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #13550]
diff --git a/ports/ChangeLog.tile b/ports/ChangeLog.tile
index a5eaec3..a473b30 100644
--- a/ports/ChangeLog.tile
+++ b/ports/ChangeLog.tile
@@ -1,3 +1,10 @@
+2013-02-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libc.abilist:
+	Add __cxa_thread_atexit_impl.
+	* sysdeps/unix/sysv/linux/tile/tilepro/nptl/libc.abilist:
+	Likewise.
+
 2013-01-10  Chris Metcalf  <cmetcalf@tilera.com>
 
 	* sysdeps/unix/sysv/linux/tile/tilegx/ldd-rewrite.sed: New file.
diff --git a/ports/sysdeps/unix/sysv/linux/alpha/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/alpha/nptl/libc.abilist
index 1d0cc7e..980e088 100644
--- a/ports/sysdeps/unix/sysv/linux/alpha/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/alpha/nptl/libc.abilist
@@ -1819,6 +1819,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/arm/nptl/libc.abilist
index ceab6b2..ce45208 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/libc.abilist
@@ -86,6 +86,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.4
  GLIBC_2.4 A
  _Exit F
diff --git a/ports/sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist
index b3510fe..067552d 100644
--- a/ports/sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist
@@ -86,6 +86,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _Exit F
diff --git a/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libc.abilist
index 3c40379..f06cc8e 100644
--- a/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libc.abilist
@@ -87,6 +87,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.4
  GLIBC_2.4 A
  _Exit F
diff --git a/ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libc.abilist
index f998b1b..9010ea7 100644
--- a/ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libc.abilist
@@ -1775,6 +1775,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist
index 7378869..f8cefd1 100644
--- a/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist
@@ -2250,3 +2250,6 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
diff --git a/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist
index df2e637..9dbbd97 100644
--- a/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist
@@ -1398,6 +1398,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _Exit F
diff --git a/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libc.abilist
index 22b3068..c7e46aa 100644
--- a/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libc.abilist
@@ -1396,6 +1396,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _Exit F
diff --git a/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
index 0efc6b5..9b6d663 100644
--- a/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist
@@ -1781,6 +1781,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libc.abilist
index d79b2df..caf74b8 100644
--- a/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libc.abilist
@@ -2088,3 +2088,6 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
diff --git a/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libc.abilist
index f617405..68d975b 100644
--- a/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libc.abilist
@@ -2088,3 +2088,6 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
diff --git a/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libc.abilist b/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libc.abilist
index d79b2df..caf74b8 100644
--- a/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libc.abilist
+++ b/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libc.abilist
@@ -2088,3 +2088,6 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
diff --git a/stdlib/Makefile b/stdlib/Makefile
index e2078f8..6f98c71 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -34,7 +34,7 @@ routines	:=							      \
 	bsearch qsort msort						      \
 	getenv putenv setenv secure-getenv				      \
 	exit on_exit atexit cxa_atexit cxa_finalize old_atexit		      \
-	quick_exit at_quick_exit cxa_at_quick_exit			      \
+	quick_exit at_quick_exit cxa_at_quick_exit cxa_thread_atexit_impl     \
 	abs labs llabs							      \
 	div ldiv lldiv							      \
 	mblen mbstowcs mbtowc wcstombs wctomb				      \
@@ -71,9 +71,11 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-makecontext2 tst-strtod6 tst-unsetenv1		    \
 		   tst-makecontext3 bug-getcontext bug-fmtmsg1		    \
 		   tst-secure-getenv tst-strtod-overflow tst-strtod-round   \
-		   tst-tininess tst-strtod-underflow
+		   tst-tininess tst-strtod-underflow tst-tls-atexit
 tests-static	:= tst-secure-getenv
 
+modules-names	= tst-tls-atexit-lib
+
 include ../Makeconfig
 
 ifeq ($(build-shared),yes)
@@ -155,3 +157,9 @@ $(objpfx)bug-getcontext: $(link-libm)
 $(objpfx)tst-strtod-round: $(link-libm)
 $(objpfx)tst-tininess: $(link-libm)
 $(objpfx)tst-strtod-underflow: $(link-libm)
+
+tst-tls-atexit-lib.so-no-z-defs = yes
+
+LDFLAGS-tst-tls-atexit = $(common-objpfx)nptl/libpthread.so \
+			 $(common-objpfx)dlfcn/libdl.so
+$(objpfx)tst-tls-atexit.out: $(objpfx)tst-tls-atexit-lib.so
diff --git a/stdlib/Versions b/stdlib/Versions
index 250bd5f..f1777df 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -106,6 +106,9 @@ libc {
   GLIBC_2.17 {
     secure_getenv;
   }
+  GLIBC_2.18 {
+    __cxa_thread_atexit_impl;
+  }
   GLIBC_PRIVATE {
     # functions which have an additional interface since they are
     # are cancelable.
@@ -114,5 +117,6 @@ libc {
     __abort_msg;
     # Used from other libraries
     __libc_secure_getenv;
+    __call_tls_dtors;
   }
 }
diff --git a/stdlib/cxa_thread_atexit_impl.c b/stdlib/cxa_thread_atexit_impl.c
new file mode 100644
index 0000000..9638efc
--- /dev/null
+++ b/stdlib/cxa_thread_atexit_impl.c
@@ -0,0 +1,102 @@
+/* Register destructors for C++ TLS variables declared with thread_local.
+   Copyright (C) 2012 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
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <ldsodefs.h>
+
+typedef void (*dtor_func) (void *);
+
+struct dtor_list
+{
+  dtor_func func;
+  void *obj;
+  struct link_map *map;
+  struct dtor_list *next;
+};
+
+static __thread struct dtor_list *tls_dtor_list;
+static __thread void *dso_symbol_cache;
+static __thread struct link_map *lm_cache;
+
+/* Register a destructor for TLS variables declared with the 'thread_local'
+   keyword.  This function is only called from code generated by the C++
+   compiler.  FUNC is the destructor function and OBJ is the object to be
+   passed to the destructor.  DSO_SYMBOL is the __dso_handle symbol that each
+   DSO has at a unique address in its map, added from crtbegin.o during the
+   linking phase.  */
+int
+__cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
+{
+  /* Prepend.  */
+  struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
+  new->func = func;
+  new->obj = obj;
+  new->next = tls_dtor_list;
+  tls_dtor_list = new;
+
+  /* See if we already encountered the DSO.  */
+  __rtld_lock_lock_recursive (GL(dl_load_lock));
+
+  if (__builtin_expect (dso_symbol_cache != dso_symbol, 0))
+    {
+      ElfW(Addr) caller = (ElfW(Addr)) dso_symbol;
+
+      struct link_map *l = _dl_find_dso_for_object (caller);
+
+      /* If the address is not recognized the call comes from the main
+         program (we hope).  */
+      lm_cache = l ? l : GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+    }
+  /* A destructor could result in a thread_local construction and the former
+     could have cleared the flag.  */
+  if (lm_cache->l_type == lt_loaded && lm_cache->l_tls_dtor_count == 0)
+    lm_cache->l_flags_1 |= DF_1_NODELETE;
+
+  new->map = lm_cache;
+  new->map->l_tls_dtor_count++;
+
+  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
+  return 0;
+}
+
+/* Call the destructors.  This is called either when a thread returns from the
+   initial function or when the process exits via the exit(3) function.  */
+void
+__call_tls_dtors (void)
+{
+  while (tls_dtor_list)
+    {
+      struct dtor_list *cur = tls_dtor_list;
+      tls_dtor_list = tls_dtor_list->next;
+
+      cur->func (cur->obj);
+
+      __rtld_lock_lock_recursive (GL(dl_load_lock));
+
+      /* Allow DSO unload if count drops to zero.  */
+      cur->map->l_tls_dtor_count--;
+      if (cur->map->l_tls_dtor_count == 0 && cur->map->l_type == lt_loaded)
+        cur->map->l_flags_1 &= ~DF_1_NODELETE;
+
+      __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
+      free (cur);
+    }
+}
+libc_hidden_def (__call_tls_dtors)
diff --git a/stdlib/exit.c b/stdlib/exit.c
index e9a2139..2e86caa 100644
--- a/stdlib/exit.c
+++ b/stdlib/exit.c
@@ -33,6 +33,9 @@ attribute_hidden
 __run_exit_handlers (int status, struct exit_function_list **listp,
 		     bool run_list_atexit)
 {
+  /* First, call the TLS destructors.  */
+  __call_tls_dtors ();
+
   /* We do it this way to handle recursive calls to exit () made by
      the functions registered with `atexit' and `on_exit'. We call
      everyone on the list and use the status value in the last
diff --git a/stdlib/tst-tls-atexit-lib.c b/stdlib/tst-tls-atexit-lib.c
new file mode 100644
index 0000000..aab28bb
--- /dev/null
+++ b/stdlib/tst-tls-atexit-lib.c
@@ -0,0 +1,36 @@
+/* Verify that DSO is unloaded only if its TLS objects are destroyed - the DSO.
+   Copyright (C) 2012 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
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+extern void *__dso_handle;
+
+typedef struct
+{
+  void *val;
+} A;
+
+/* We only care about the destructor.  */
+void A_dtor (void *obj)
+{
+  ((A *)obj)->val = obj;
+}
+
+void do_foo (void)
+{
+  static __thread A b;
+  __cxa_thread_atexit_impl (A_dtor, &b, __dso_handle);
+}
diff --git a/stdlib/tst-tls-atexit.c b/stdlib/tst-tls-atexit.c
new file mode 100644
index 0000000..b7312cb
--- /dev/null
+++ b/stdlib/tst-tls-atexit.c
@@ -0,0 +1,111 @@
+/* Verify that DSO is unloaded only if its TLS objects are destroyed.
+   Copyright (C) 2012 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
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* There are two tests in this test case.  The first is implicit where it is
+   assumed that the destructor call on exit of the LOAD function does not
+   segfault.  The other is a verification that after the thread has exited, a
+   dlclose will unload the DSO.  */
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+void *handle;
+pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+
+void *
+load (void *u)
+{
+  pthread_mutex_lock (&m);
+  handle = dlopen ("$ORIGIN/tst-tls-atexit-lib.so", RTLD_LAZY);
+  if (!handle)
+    {
+      printf ("Unable to load DSO: %s\n", dlerror ());
+      return (void *) (uintptr_t) 1;
+    }
+
+  void (*foo) (void) = (void (*) (void)) dlsym(handle, "do_foo");
+
+  if (!foo)
+    {
+      printf ("Unable to find symbol: %s\n", dlerror ());
+      exit (1);
+    }
+
+  foo ();
+
+  /* This should not unload the DSO.  If it does, then the thread exit will
+     result in a segfault.  */
+  dlclose (handle);
+  pthread_mutex_unlock (&m);
+
+  return NULL;
+}
+
+int
+main (void)
+{
+  pthread_t t;
+  int ret;
+  void *thr_ret;
+
+  if ((ret = pthread_create (&t, NULL, load, NULL)) != 0)
+    {
+      printf ("pthread_create failed: %s\n", strerror (ret));
+      return 1;
+    }
+
+  if ((ret = pthread_join (t, &thr_ret)) != 0)
+    {
+      printf ("pthread_create failed: %s\n", strerror (ret));
+      return 1;
+    }
+
+  if (thr_ret != NULL)
+    return 1;
+
+  /* Now this should unload the DSO.  */
+  dlclose (handle);
+
+  /* Run through our maps and ensure that the DSO is unloaded.  */
+  FILE *f = fopen ("/proc/self/maps", "r");
+
+  if (f == NULL)
+    {
+      perror ("Failed to open /proc/self/maps");
+      fprintf (stderr, "Skipping verification of DSO unload\n");
+      return 0;
+    }
+
+  char *line = NULL;
+  size_t s = 0;
+  while (getline (&line, &s, f) > 0)
+    {
+      if (strstr (line, "tst-tls-atexit-lib.so"))
+        {
+	  printf ("DSO not unloaded yet:\n%s", line);
+	  return 1;
+	}
+    }
+  free (line);
+
+  return 0;
+}
diff --git a/sysdeps/unix/sysv/linux/i386/nptl/libc.abilist b/sysdeps/unix/sysv/linux/i386/nptl/libc.abilist
index 67d5929..3cb314d 100644
--- a/sysdeps/unix/sysv/linux/i386/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/nptl/libc.abilist
@@ -1819,6 +1819,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
index 8e45958..f27b48b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist
@@ -1781,6 +1781,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
index 8eaaccd..195b587 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist
@@ -87,6 +87,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.3
  GLIBC_2.3 A
  _Exit F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
index d9914ff..b6256d5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
@@ -1771,6 +1771,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
index ef1ead3..265f66d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
@@ -92,6 +92,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _Exit F
diff --git a/sysdeps/unix/sysv/linux/sh/nptl/libc.abilist b/sysdeps/unix/sysv/linux/sh/nptl/libc.abilist
index 733b550..a653292 100644
--- a/sysdeps/unix/sysv/linux/sh/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/nptl/libc.abilist
@@ -92,6 +92,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _Exit F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libc.abilist
index 3a96ea8..9defbdf 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libc.abilist
@@ -1776,6 +1776,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _IO_adjust_wcolumn F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist
index aa892b8..35987fa 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist
@@ -97,6 +97,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2
  GLIBC_2.2 A
  _Exit F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/nptl/libc.abilist
index a42d424..914b590 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/nptl/libc.abilist
@@ -88,6 +88,9 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F
 GLIBC_2.2.5
  GLIBC_2.2.5 A
  _Exit F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/nptl/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/nptl/libc.abilist
index 108b80f..0f64c8d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/nptl/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/nptl/libc.abilist
@@ -2086,3 +2086,6 @@ GLIBC_2.17
  clock_nanosleep F
  clock_settime F
  secure_getenv F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __cxa_thread_atexit_impl F

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   33 ++++++
 Versions.def                                       |    1 +
 include/link.h                                     |    3 +
 include/stdlib.h                                   |    5 +
 nptl/pthread_create.c                              |    3 +
 ports/ChangeLog.alpha                              |    5 +
 ports/ChangeLog.arm                                |    5 +
 ports/ChangeLog.ia64                               |    5 +
 ports/ChangeLog.m68k                               |    7 ++
 ports/ChangeLog.mips                               |    9 ++
 ports/ChangeLog.powerpc                            |    7 ++
 ports/ChangeLog.tile                               |    7 ++
 .../unix/sysv/linux/alpha/nptl/libc.abilist        |    3 +
 .../sysdeps/unix/sysv/linux/arm/nptl/libc.abilist  |    3 +
 .../sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist |    3 +
 .../sysv/linux/m68k/coldfire/nptl/libc.abilist     |    3 +
 .../unix/sysv/linux/m68k/m680x0/nptl/libc.abilist  |    3 +
 .../unix/sysv/linux/mips/mips32/nptl/libc.abilist  |    3 +
 .../sysv/linux/mips/mips64/n32/nptl/libc.abilist   |    3 +
 .../sysv/linux/mips/mips64/n64/nptl/libc.abilist   |    3 +
 .../powerpc/powerpc32/nofpu/nptl/libc.abilist      |    3 +
 .../linux/tile/tilegx/tilegx32/nptl/libc.abilist   |    3 +
 .../linux/tile/tilegx/tilegx64/nptl/libc.abilist   |    3 +
 .../unix/sysv/linux/tile/tilepro/nptl/libc.abilist |    3 +
 stdlib/Makefile                                    |   12 ++-
 stdlib/Versions                                    |    4 +
 stdlib/cxa_thread_atexit_impl.c                    |  102 ++++++++++++++++++
 stdlib/exit.c                                      |    3 +
 stdlib/tst-tls-atexit-lib.c                        |   36 +++++++
 stdlib/tst-tls-atexit.c                            |  111 ++++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/nptl/libc.abilist     |    3 +
 .../linux/powerpc/powerpc32/fpu/nptl/libc.abilist  |    3 +
 .../sysv/linux/powerpc/powerpc64/nptl/libc.abilist |    3 +
 .../unix/sysv/linux/s390/s390-32/nptl/libc.abilist |    3 +
 .../unix/sysv/linux/s390/s390-64/nptl/libc.abilist |    3 +
 sysdeps/unix/sysv/linux/sh/nptl/libc.abilist       |    3 +
 .../sysv/linux/sparc/sparc32/nptl/libc.abilist     |    3 +
 .../sysv/linux/sparc/sparc64/nptl/libc.abilist     |    3 +
 .../unix/sysv/linux/x86_64/64/nptl/libc.abilist    |    3 +
 .../unix/sysv/linux/x86_64/x32/nptl/libc.abilist   |    3 +
 40 files changed, 422 insertions(+), 2 deletions(-)
 create mode 100644 stdlib/cxa_thread_atexit_impl.c
 create mode 100644 stdlib/tst-tls-atexit-lib.c
 create mode 100644 stdlib/tst-tls-atexit.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]