This source file includes following definitions.
- destructorsList
- destructorsMutex
- setValue
- value
- callDestructor
- tlsKeyCount
- tlsKeys
- threadSpecificKeyCreate
- threadSpecificKeyDelete
- threadSpecificSet
- threadSpecificGet
- ThreadSpecificThreadExit
#include "config.h"
#include "ThreadSpecific.h"
#if OS(WIN)
#include "StdLibExtras.h"
#include "ThreadingPrimitives.h"
#include "wtf/DoublyLinkedList.h"
namespace WTF {
static DoublyLinkedList<PlatformThreadSpecificKey>& destructorsList()
{
DEFINE_STATIC_LOCAL(DoublyLinkedList<PlatformThreadSpecificKey>, staticList, ());
return staticList;
}
static Mutex& destructorsMutex()
{
DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
return staticMutex;
}
class PlatformThreadSpecificKey : public DoublyLinkedListNode<PlatformThreadSpecificKey> {
public:
friend class DoublyLinkedListNode<PlatformThreadSpecificKey>;
PlatformThreadSpecificKey(void (*destructor)(void *))
: m_destructor(destructor)
{
m_tlsKey = TlsAlloc();
if (m_tlsKey == TLS_OUT_OF_INDEXES)
CRASH();
}
~PlatformThreadSpecificKey()
{
TlsFree(m_tlsKey);
}
void setValue(void* data) { TlsSetValue(m_tlsKey, data); }
void* value() { return TlsGetValue(m_tlsKey); }
void callDestructor()
{
if (void* data = value())
m_destructor(data);
}
private:
void (*m_destructor)(void *);
DWORD m_tlsKey;
PlatformThreadSpecificKey* m_prev;
PlatformThreadSpecificKey* m_next;
};
long& tlsKeyCount()
{
static long count;
return count;
}
DWORD* tlsKeys()
{
static DWORD keys[kMaxTlsKeySize];
return keys;
}
void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
{
*key = new PlatformThreadSpecificKey(destructor);
MutexLocker locker(destructorsMutex());
destructorsList().push(*key);
}
void threadSpecificKeyDelete(ThreadSpecificKey key)
{
MutexLocker locker(destructorsMutex());
destructorsList().remove(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++) {
ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(tlsKeys()[i]));
if (data)
data->destructor(data);
}
MutexLocker locker(destructorsMutex());
PlatformThreadSpecificKey* key = destructorsList().head();
while (key) {
PlatformThreadSpecificKey* nextKey = key->next();
key->callDestructor();
key = nextKey;
}
}
}
#endif