1 //===----------------------- cxa_thread_atexit.cpp ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "abort_message.h"
11 #include "cxxabi.h"
12 #include <cstdlib>
13 #include <pthread.h>
14 
15 namespace __cxxabiv1 {
16 
17   using Dtor = void(*)(void*);
18 
19   extern "C"
20 #ifndef HAVE___CXA_THREAD_ATEXIT_IMPL
21   // A weak symbol is used to detect this function's presence in the C library
22   // at runtime, even if libc++ is built against an older libc
23   __attribute__((__weak__))
24 #endif
25   int __cxa_thread_atexit_impl(Dtor, void*, void*);
26 
27 #ifndef HAVE___CXA_THREAD_ATEXIT_IMPL
28 
29 namespace {
30   // This implementation is used if the C library does not provide
31   // __cxa_thread_atexit_impl() for us.  It has a number of limitations that are
32   // difficult to impossible to address without ..._impl():
33   //
34   // - dso_symbol is ignored.  This means that a shared library may be unloaded
35   //   (via dlclose()) before its thread_local destructors have run.
36   //
37   // - thread_local destructors for the main thread are run by the destructor of
38   //   a static object.  This is later than expected; they should run before the
39   //   destructors of any objects with static storage duration.
40   //
41   // - thread_local destructors on non-main threads run on the first iteration
42   //   through the pthread_key destructors.  std::notify_all_at_thread_exit()
43   //   and similar functions must be careful to wait until the second iteration
44   //   to provide their intended ordering guarantees.
45   //
46   // Another limitation, though one shared with ..._impl(), is that any
47   // thread_locals that are first initialized after non-thread_local global
48   // destructors begin to run will not be destroyed.  [basic.start.term] states
49   // that all thread_local destructors are sequenced before the destruction of
50   // objects with static storage duration, resulting in a contradiction if a
51   // thread_local is constructed after that point.  Thus we consider such
52   // programs ill-formed, and don't bother to run those destructors.  (If the
53   // program terminates abnormally after such a thread_local is constructed,
54   // the destructor is not expected to run and thus there is no contradiction.
55   // So construction still has to work.)
56 
57   struct DtorList {
58     Dtor dtor;
59     void* obj;
60     DtorList* next;
61   };
62 
63   // The linked list of thread-local destructors to run
64   __thread DtorList* dtors = nullptr;
65   // True if the destructors are currently scheduled to run on this thread
66   __thread bool dtors_alive = false;
67   // Used to trigger destructors on thread exit; value is ignored
68   pthread_key_t dtors_key;
69 
70   void run_dtors(void*) {
71     while (auto head = dtors) {
72       dtors = head->next;
73       head->dtor(head->obj);
74       std::free(head);
75     }
76 
77     dtors_alive = false;
78   }
79 
80   struct DtorsManager {
81     DtorsManager() {
82       // There is intentionally no matching pthread_key_delete call, as
83       // __cxa_thread_atexit() may be called arbitrarily late (for example, from
84       // global destructors or atexit() handlers).
85       if (pthread_key_create(&dtors_key, run_dtors) != 0) {
86         abort_message("pthread_key_create() failed in __cxa_thread_atexit()");
87       }
88     }
89 
90     ~DtorsManager() {
91       // pthread_key destructors do not run on threads that call exit()
92       // (including when the main thread returns from main()), so we explicitly
93       // call the destructor here.  This runs at exit time (potentially earlier
94       // if libc++abi is dlclose()'d).  Any thread_locals initialized after this
95       // point will not be destroyed.
96       run_dtors(nullptr);
97     }
98   };
99 } // namespace
100 
101 #endif // HAVE__CXA_THREAD_ATEXIT_IMPL
102 
103 extern "C" {
104 
105   _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void* obj, void* dso_symbol) throw() {
106 #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
107     return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
108 #else
109     if (__cxa_thread_atexit_impl) {
110       return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
111     } else {
112       // Initialize the dtors pthread_key (uses __cxa_guard_*() for one-time
113       // initialization and __cxa_atexit() for destruction)
114       static DtorsManager manager;
115 
116       if (!dtors_alive) {
117         if (pthread_setspecific(dtors_key, &dtors_key) != 0) {
118           return -1;
119         }
120         dtors_alive = true;
121       }
122 
123       auto head = static_cast<DtorList*>(std::malloc(sizeof(DtorList)));
124       if (!head) {
125         return -1;
126       }
127 
128       head->dtor = dtor;
129       head->obj = obj;
130       head->next = dtors;
131       dtors = head;
132 
133       return 0;
134     }
135 #endif // HAVE___CXA_THREAD_ATEXIT_IMPL
136   }
137 
138 } // extern "C"
139 } // namespace __cxxabiv1
140