From b818cc48478479a5da11cd468f1cba9ecc78af3b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 7 Nov 2014 08:41:00 -0500 Subject: [PATCH] Bug 1093823 - Avoid valgrind report from ThreadLocal. r=froydnj --- mfbt/ThreadLocal.h | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/mfbt/ThreadLocal.h b/mfbt/ThreadLocal.h index 28015de22e22..99bc5e05fe32 100644 --- a/mfbt/ThreadLocal.h +++ b/mfbt/ThreadLocal.h @@ -30,6 +30,7 @@ __declspec(dllimport) unsigned long __stdcall TlsAlloc(); #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/NullPtr.h" +#include "mozilla/TypeTraits.h" namespace mozilla { @@ -78,10 +79,20 @@ class ThreadLocal typedef pthread_key_t key_t; #endif - union Helper + // Integral types narrower than void* must be extended to avoid + // warnings from valgrind on some platforms. This helper type + // achieves that without penalizing the common case of ThreadLocals + // instantiated using a pointer type. + template + struct Helper { - void* mPtr; - T mValue; + typedef uintptr_t Type; + }; + + template + struct Helper + { + typedef S *Type; }; public: @@ -102,6 +113,9 @@ template inline bool ThreadLocal::init() { + static_assert(mozilla::IsPointer::value || mozilla::IsIntegral::value, + "mozilla::ThreadLocal must be used with a pointer or " + "integral type"); static_assert(sizeof(T) <= sizeof(void*), "mozilla::ThreadLocal can't be used for types larger than " "a pointer"); @@ -120,13 +134,13 @@ inline T ThreadLocal::get() const { MOZ_ASSERT(initialized()); - Helper h; + void* h; #ifdef XP_WIN - h.mPtr = TlsGetValue(mKey); + h = TlsGetValue(mKey); #else - h.mPtr = pthread_getspecific(mKey); + h = pthread_getspecific(mKey); #endif - return h.mValue; + return static_cast(reinterpret_cast::Type>(h)); } template @@ -134,12 +148,11 @@ inline void ThreadLocal::set(const T aValue) { MOZ_ASSERT(initialized()); - Helper h; - h.mValue = aValue; + void* h = reinterpret_cast(static_cast::Type>(aValue)); #ifdef XP_WIN - bool succeeded = TlsSetValue(mKey, h.mPtr); + bool succeeded = TlsSetValue(mKey, h); #else - bool succeeded = !pthread_setspecific(mKey, h.mPtr); + bool succeeded = !pthread_setspecific(mKey, h); #endif if (!succeeded) { MOZ_CRASH();