]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - stdlib/cxa_thread_atexit_impl.c
hurd: Fix build
[thirdparty/glibc.git] / stdlib / cxa_thread_atexit_impl.c
index 8e26380799c3abc5bedfb3aa079880fc7c64d44e..4501399c31391ad336316a34f91a0a98968ddc6a 100644 (file)
@@ -1,5 +1,5 @@
 /* Register destructors for C++ TLS variables declared with thread_local.
-   Copyright (C) 2013-2015 Free Software Foundation, Inc.
+   Copyright (C) 2013-2018 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
    combinations of all three functions are the link map list, a link map for a
    DSO and the link map member l_tls_dtor_count.
 
-   __cxa_thread_atexit_impl acquires the load_lock before accessing any shared
-   state and hence multiple of its instances can safely execute concurrently.
+   __cxa_thread_atexit_impl acquires the dl_load_lock before accessing any
+   shared state and hence multiple of its instances can safely execute
+   concurrently.
 
-   _dl_close_worker acquires the load_lock before accessing any shared state as
-   well and hence can concurrently execute multiple of its own instances as
+   _dl_close_worker acquires the dl_load_lock before accessing any shared state
+   as well and hence can concurrently execute multiple of its own instances as
    well as those of __cxa_thread_atexit_impl safely.  Not all accesses to
-   l_tls_dtor_count are protected by the load lock, so we need to synchronize
-   using atomics.
+   l_tls_dtor_count are protected by the dl_load_lock, so we need to
+   synchronize using atomics.
 
    __call_tls_dtors accesses the l_tls_dtor_count without taking the lock; it
    decrements the value by one.  It does not need the big lock because it does
@@ -51,8 +52,8 @@
    it is safe to unload the DSO.  Hence, to ensure that this does not happen,
    the following conditions must be met:
 
-   1. In _dl_close_worker, the l_tls_dtor_count load happens before the DSO
-      is unload and its link map is freed
+   1. In _dl_close_worker, the l_tls_dtor_count load happens before the DSO is
+      unloaded and its link map is freed
    2. The link map dereference in __call_tls_dtors happens before the
       l_tls_dtor_count dereference.
 
@@ -97,6 +98,10 @@ static __thread struct link_map *lm_cache;
 int
 __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
 {
+#ifdef PTR_MANGLE
+  PTR_MANGLE (func);
+#endif
+
   /* Prepend.  */
   struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
   new->func = func;
@@ -122,7 +127,7 @@ __cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
 
   /* This increment may only be concurrently observed either by the decrement
      in __call_tls_dtors since the other l_tls_dtor_count access in
-     _dl_close_worker is protected by the load lock.  The execution in
+     _dl_close_worker is protected by the dl_load_lock.  The execution in
      __call_tls_dtors does not really depend on this value beyond the fact that
      it should be atomic, so Relaxed MO should be sufficient.  */
   atomic_fetch_add_relaxed (&lm_cache->l_tls_dtor_count, 1);
@@ -141,9 +146,13 @@ __call_tls_dtors (void)
   while (tls_dtor_list)
     {
       struct dtor_list *cur = tls_dtor_list;
+      dtor_func func = cur->func;
+#ifdef PTR_DEMANGLE
+      PTR_DEMANGLE (func);
+#endif
 
       tls_dtor_list = tls_dtor_list->next;
-      cur->func (cur->obj);
+      func (cur->obj);
 
       /* Ensure that the MAP dereference happens before
         l_tls_dtor_count decrement.  That way, we protect this access from a