[PATCH] D21803: [libcxxabi] Provide a fallback __cxa_thread_atexit() implementation

Tavian Barnes via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 29 12:40:53 PDT 2016


tavianator added a comment.

In http://reviews.llvm.org/D21803#470086, @bcraig wrote:

> It also intentionally leaks the pthread key.  Does the __thread_specific_ptr rationale hold for this change as well?


Hmm, maybe?  If other global destructors run after ~DtorListHolder(), and they cause a thread_local to be initialized for the first time, __cxa_thread_atexit() might be called again.  I was thinking that dtors would get re-initialized in that case but it appears it does not.  So yeah, I think I'll need to leak the pthread_key_t.

I'm not sure how to avoid leaking the actual thread_local objects that get created in that situation.  There's nothing left to trigger run_dtors() a second time.


================
Comment at: src/cxa_thread_atexit.cpp:64-90
@@ -18,8 +63,29 @@
+_LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void *obj,
                                             void *dso_symbol) throw() {
-  extern int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);
-  return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
-}
+  extern int __cxa_thread_atexit_impl(Dtor, void *, void *)
+    __attribute__((__weak__));
+
+  if (__cxa_thread_atexit_impl) {
+    return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
+  } else {
+    static DtorListHolder dtors;
+
+    auto head = static_cast<DtorList*>(std::malloc(sizeof(DtorList)));
+    if (!head) {
+      return -1;
+    }
+
+    head->dtor = dtor;
+    head->obj = obj;
+    head->next = dtors.get();
+
+    if (!dtors.set(head)) {
+      std::free(head);
+      return -1;
+    }
 
-#endif // HAVE__CXA_THREAD_ATEXIT_IMPL
+    return 0;
+  }
+}
 
 } // extern "C"
----------------
majnemer wrote:
> I think that this should be an opt-in mechanism, there are platforms that presumably never need to pay the cost of the unused code (macOS comes to mind).
This file is only built for UNIX AND NOT (APPLE OR CYGWIN).  Other platforms use something other than __cxa_thread_atexit() I assume.


http://reviews.llvm.org/D21803





More information about the cfe-commits mailing list