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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits