summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf/ThreadSpecificWin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WTF/wtf/ThreadSpecificWin.cpp')
-rw-r--r--Source/WTF/wtf/ThreadSpecificWin.cpp90
1 files changed, 86 insertions, 4 deletions
diff --git a/Source/WTF/wtf/ThreadSpecificWin.cpp b/Source/WTF/wtf/ThreadSpecificWin.cpp
index d72996a7a..61a594251 100644
--- a/Source/WTF/wtf/ThreadSpecificWin.cpp
+++ b/Source/WTF/wtf/ThreadSpecificWin.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Jian Li <jianli@chromium.org>
+ * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,15 +20,72 @@
*/
#include "config.h"
-
#include "ThreadSpecific.h"
-#if USE(PTHREADS)
-#error This file should not be compiled by ports that do not use Windows native ThreadSpecific implementation.
-#endif
+#include "StdLibExtras.h"
+#include "ThreadingPrimitives.h"
+
+#if !USE(PTHREADS)
namespace WTF {
+static Mutex& destructorsMutex()
+{
+ DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
+ return staticMutex;
+}
+
+class ThreadSpecificKeyValue {
+public:
+ ThreadSpecificKeyValue(void (*destructor)(void *))
+ : m_destructor(destructor)
+ {
+ m_tlsKey = TlsAlloc();
+ if (m_tlsKey == TLS_OUT_OF_INDEXES)
+ CRASH();
+
+ MutexLocker locker(destructorsMutex());
+ m_next = m_first;
+ m_first = this;
+ }
+
+ ~ThreadSpecificKeyValue()
+ {
+ MutexLocker locker(destructorsMutex());
+ ThreadSpecificKeyValue** next = &m_first;
+ while (*next != this) {
+ ASSERT(*next);
+ next = &(*next)->m_next;
+ }
+ *next = (*next)->m_next;
+
+ TlsFree(m_tlsKey);
+ }
+
+ void setValue(void* data) { TlsSetValue(m_tlsKey, data); }
+ void* value() { return TlsGetValue(m_tlsKey); }
+
+ static void callDestructors()
+ {
+ MutexLocker locker(destructorsMutex());
+ ThreadSpecificKeyValue* next = m_first;
+ while (next) {
+ if (void* data = next->value())
+ next->m_destructor(data);
+ next = next->m_next;
+ }
+ }
+
+private:
+ void (*m_destructor)(void *);
+ DWORD m_tlsKey;
+ ThreadSpecificKeyValue* m_next;
+
+ static ThreadSpecificKeyValue* m_first;
+};
+
+ThreadSpecificKeyValue* ThreadSpecificKeyValue::m_first = 0;
+
long& tlsKeyCount()
{
static long count;
@@ -40,6 +98,26 @@ DWORD* tlsKeys()
return keys;
}
+void ThreadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
+{
+ *key = new ThreadSpecificKeyValue(destructor);
+}
+
+void ThreadSpecificKeyDelete(ThreadSpecificKey key)
+{
+ delete key;
+}
+
+void ThreadSpecificSet(ThreadSpecificKey key, void* data)
+{
+ key->setValue(data);
+}
+
+void* ThreadSpecificGet(ThreadSpecificKey key)
+{
+ return key->value();
+}
+
void ThreadSpecificThreadExit()
{
for (long i = 0; i < tlsKeyCount(); i++) {
@@ -48,6 +126,10 @@ void ThreadSpecificThreadExit()
if (data)
data->destructor(data);
}
+
+ ThreadSpecificKeyValue::callDestructors();
}
} // namespace WTF
+
+#endif // !USE(PTHREADS)