From ac04a6cfb80a7e7074b70f5fcf678312b390a957 Mon Sep 17 00:00:00 2001 From: Nate Rosenblum Date: Fri, 7 Aug 2015 10:47:05 -0700 Subject: [PATCH] Fix OSX + Windows build Commit 257ee89 added a static destruction helper to avoid notional "leaks" of TLS on main thread exit. This helper fails to compile on OS X (and presumably Windows, though I haven't checked), which lacks the __thread storage class StaticMeta::tls_ member. This patch fixes the builds. Do note that the static cleanup mechanism may be somewhat brittle and atexit(3) may be a more suitable approach to releasing the main thread's TLS if it's highly desirable for this memory to not be reported "reachable" by Valgrind at exit. --- util/thread_local.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/util/thread_local.cc b/util/thread_local.cc index 349d5d24e..969690739 100644 --- a/util/thread_local.cc +++ b/util/thread_local.cc @@ -140,13 +140,29 @@ ThreadLocalPtr::StaticMeta::StaticMeta() : next_instance_id_(0) { // OnThreadExit is not getting called on the main thread. // Call through the static destructor mechanism to avoid memory leak. + // + // Caveats: ~A() will be invoked _after_ ~StaticMeta for the global + // singleton (destructors are invoked in reverse order of constructor + // _completion_); the latter must not mutate internal members. This + // cleanup mechanism inherently relies on use-after-release of the + // StaticMeta, and is brittle with respect to compiler-specific handling + // of memory backing destructed statically-scoped objects. Perhaps + // registering with atexit(3) would be more robust. + // + // This is not required on Windows. +#if !defined(OS_WIN) static struct A { ~A() { +#if defined(OS_MACOSX) + ThreadData* tls_ = + static_cast(pthread_getspecific(Instance()->pthread_key_)); +#endif if (tls_) { OnThreadExit(tls_); } } } a; +#endif head_.next = &head_; head_.prev = &head_;