Bug 756965 - Allow mozilla::ThreadLocal to store integer types smaller than, or as large as, a pointer. r=Waldo

This commit is contained in:
Mike Hommey 2012-05-22 08:43:55 +02:00
parent 2682d05bb2
commit 96de05d930
3 changed files with 22 additions and 12 deletions

View File

@ -72,12 +72,17 @@ class ThreadLocal
typedef pthread_key_t key_t;
#endif
union Helper {
void *ptr;
T value;
};
public:
MOZ_WARN_UNUSED_RESULT inline bool init();
inline T* get() const;
inline T get() const;
inline bool set(const T* value);
inline bool set(const T value);
bool initialized() const {
return inited;
@ -91,6 +96,7 @@ class ThreadLocal
template <typename T>
inline bool
ThreadLocal<T>::init() {
MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void *), "mozilla::ThreadLocal can't be used for types larger than a pointer");
MOZ_ASSERT(!initialized());
#ifdef XP_WIN
key = TlsAlloc();
@ -102,24 +108,28 @@ ThreadLocal<T>::init() {
}
template <typename T>
inline T*
inline T
ThreadLocal<T>::get() const {
MOZ_ASSERT(initialized());
Helper h;
#ifdef XP_WIN
return reinterpret_cast<T*>(TlsGetValue(key));
h.ptr = TlsGetValue(key);
#else
return reinterpret_cast<T*>(pthread_getspecific(key));
h.ptr = pthread_getspecific(key);
#endif
return h.value;
}
template <typename T>
inline bool
ThreadLocal<T>::set(const T* value) {
ThreadLocal<T>::set(const T value) {
MOZ_ASSERT(initialized());
Helper h;
h.value = value;
#ifdef XP_WIN
return TlsSetValue(key, const_cast<T*>(value));
return TlsSetValue(key, h.ptr);
#else
return !pthread_setspecific(key, value);
return !pthread_setspecific(key, h.ptr);
#endif
}

View File

@ -69,8 +69,8 @@ using namespace mozilla;
#endif
mozilla::ThreadLocal<ProfileStack> tlsStack;
mozilla::ThreadLocal<TableTicker> tlsTicker;
mozilla::ThreadLocal<ProfileStack *> tlsStack;
mozilla::ThreadLocal<TableTicker *> tlsTicker;
// We need to track whether we've been initialized otherwise
// we end up using tlsStack without initializing it.
// Because tlsStack is totally opaque to us we can't reuse

View File

@ -17,8 +17,8 @@ using mozilla::TimeDuration;
struct ProfileStack;
class TableTicker;
extern mozilla::ThreadLocal<ProfileStack> tlsStack;
extern mozilla::ThreadLocal<TableTicker> tlsTicker;
extern mozilla::ThreadLocal<ProfileStack *> tlsStack;
extern mozilla::ThreadLocal<TableTicker *> tlsTicker;
extern bool stack_key_initialized;
#ifndef SAMPLE_FUNCTION_NAME