tavianator updated this revision to Diff 62218.
tavianator added a comment.
Added error handling for pthread_key uses
http://reviews.llvm.org/D21803
Files:
cmake/config-ix.cmake
src/CMakeLists.txt
src/cxa_thread_atexit.cpp
test/CMakeLists.txt
test/cxa_thread_atexit_test.pass.cpp
test/libcxxabi/test/config.py
test/lit.site.cfg.in
Index: test/lit.site.cfg.in
===================================================================
--- test/lit.site.cfg.in
+++ test/lit.site.cfg.in
@@ -13,7 +13,6 @@
config.enable_32bit = "@LIBCXXABI_BUILD_32_BITS@"
config.target_info = "@LIBCXXABI_TARGET_INFO@"
config.executor = "@LIBCXXABI_EXECUTOR@"
-config.thread_atexit = "@LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL@"
config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@"
config.enable_shared = "@LIBCXX_ENABLE_SHARED@"
config.enable_exceptions = "@LIBCXXABI_ENABLE_EXCEPTIONS@"
Index: test/libcxxabi/test/config.py
===================================================================
--- test/libcxxabi/test/config.py
+++ test/libcxxabi/test/config.py
@@ -37,8 +37,6 @@
super(Configuration, self).configure_features()
if not self.get_lit_bool('enable_exceptions', True):
self.config.available_features.add('libcxxabi-no-exceptions')
- if self.get_lit_bool('thread_atexit', True):
- self.config.available_features.add('thread_atexit')
def configure_compile_flags(self):
self.cxx.compile_flags += ['-DLIBCXXABI_NO_TIMER']
Index: test/cxa_thread_atexit_test.pass.cpp
===================================================================
--- test/cxa_thread_atexit_test.pass.cpp
+++ test/cxa_thread_atexit_test.pass.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
// REQUIRES: linux
-// REQUIRES: thread_atexit
#include <assert.h>
#include <cxxabi.h>
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
@@ -16,7 +16,6 @@
pythonize_bool(LIBCXXABI_ENABLE_THREADS)
pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS)
pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
-pythonize_bool(LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
set(LIBCXXABI_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
"TargetInfo to use when setting up test environment.")
set(LIBCXXABI_EXECUTOR "None" CACHE STRING
Index: src/cxa_thread_atexit.cpp
===================================================================
--- src/cxa_thread_atexit.cpp
+++ src/cxa_thread_atexit.cpp
@@ -8,19 +8,85 @@
//===----------------------------------------------------------------------===//
#include "cxxabi.h"
+#include <cstdlib>
+#include <pthread.h>
+#include "abort_message.h"
namespace __cxxabiv1 {
-extern "C" {
+namespace {
+ typedef void (*Dtor)(void *);
+
+ struct DtorList {
+ Dtor dtor;
+ void* obj;
+ DtorList* next;
+ };
+
+ void run_dtors(void* ptr) {
+ auto elem = static_cast<DtorList*>(ptr);
+ while (elem) {
+ auto saved = elem;
+ elem = elem->next;
+ saved->dtor(saved->obj);
+ std::free(saved);
+ }
+ }
+
+ class DtorListHolder {
+ public:
+ DtorListHolder() {
+ if (pthread_key_create(&key_, run_dtors) != 0) {
+ abort_message("cannot create pthread key for __cxa_thread_atexit()");
+ }
+ }
+
+ ~DtorListHolder() {
+ run_dtors(get());
+ pthread_key_delete(key_);
+ }
+
+ DtorList* get() {
+ return static_cast<DtorList*>(pthread_getspecific(key_));
+ }
+
+ bool set(DtorList* list) {
+ return pthread_setspecific(key_, list) == 0;
+ }
+
+ private:
+ pthread_key_t key_;
+ };
+} // namespace
-#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
+extern "C" {
-_LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*dtor)(void *), void *obj,
+_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"
} // namespace __cxxabiv1
Index: src/CMakeLists.txt
===================================================================
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -41,10 +41,6 @@
include_directories("${LIBCXXABI_LIBCXX_INCLUDES}")
-if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
- add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL)
-endif()
-
# Generate library list
set(libraries ${LIBCXXABI_CXX_ABI_LIBRARIES})
Index: cmake/config-ix.cmake
===================================================================
--- cmake/config-ix.cmake
+++ cmake/config-ix.cmake
@@ -43,5 +43,3 @@
check_library_exists(dl dladdr "" LIBCXXABI_HAS_DL_LIB)
check_library_exists(pthread pthread_once "" LIBCXXABI_HAS_PTHREAD_LIB)
check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXXABI_HAS_GCC_S_LIB)
-check_library_exists(c __cxa_thread_atexit_impl ""
- LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits