15a1d355fSStephan Aßmus// ThreadLocal.cpp
25a1d355fSStephan Aßmus
35a1d355fSStephan Aßmus#include <new>
45a1d355fSStephan Aßmus
55a1d355fSStephan Aßmus#include <OS.h>
65a1d355fSStephan Aßmus
75a1d355fSStephan Aßmus#include "HashMap.h"
85a1d355fSStephan Aßmus#include "ThreadLocal.h"
95a1d355fSStephan Aßmus
105a1d355fSStephan Aßmus// ThreadLocalFreeHandler
115a1d355fSStephan Aßmus
125a1d355fSStephan Aßmus// constructor
135a1d355fSStephan AßmusThreadLocalFreeHandler::ThreadLocalFreeHandler()
145a1d355fSStephan Aßmus{
155a1d355fSStephan Aßmus}
165a1d355fSStephan Aßmus
175a1d355fSStephan Aßmus// destructor
185a1d355fSStephan AßmusThreadLocalFreeHandler::~ThreadLocalFreeHandler()
195a1d355fSStephan Aßmus{
205a1d355fSStephan Aßmus}
215a1d355fSStephan Aßmus
225a1d355fSStephan Aßmus
235a1d355fSStephan Aßmus// ThreadLocal
245a1d355fSStephan Aßmus
255a1d355fSStephan Aßmus// ThreadLocalMap
265a1d355fSStephan Aßmusstruct ThreadLocal::ThreadLocalMap
275a1d355fSStephan Aßmus	: public SynchronizedHashMap<HashKey32<thread_id>, void*> {
285a1d355fSStephan Aßmus};
295a1d355fSStephan Aßmus
305a1d355fSStephan Aßmus// constructor
315a1d355fSStephan AßmusThreadLocal::ThreadLocal(ThreadLocalFreeHandler* freeHandler)
325a1d355fSStephan Aßmus	: fMap(NULL),
335a1d355fSStephan Aßmus	  fFreeHandler(freeHandler)
345a1d355fSStephan Aßmus{
355a1d355fSStephan Aßmus	fMap = new(std::nothrow) ThreadLocalMap;
365a1d355fSStephan Aßmus}
375a1d355fSStephan Aßmus
385a1d355fSStephan Aßmus// destructor
395a1d355fSStephan AßmusThreadLocal::~ThreadLocal()
405a1d355fSStephan Aßmus{
415a1d355fSStephan Aßmus	delete fMap;
425a1d355fSStephan Aßmus}
435a1d355fSStephan Aßmus
445a1d355fSStephan Aßmus// Set
455a1d355fSStephan Aßmusstatus_t
465a1d355fSStephan AßmusThreadLocal::Set(void* data)
475a1d355fSStephan Aßmus{
485a1d355fSStephan Aßmus	if (!fMap)
495a1d355fSStephan Aßmus		return B_NO_MEMORY;
505a1d355fSStephan Aßmus	thread_id thread = find_thread(NULL);
515a1d355fSStephan Aßmus	fMap->Lock();
525a1d355fSStephan Aßmus	// free old data, if any
535a1d355fSStephan Aßmus	if (fFreeHandler &&fMap->ContainsKey(thread))
545a1d355fSStephan Aßmus		fFreeHandler->Free(fMap->Get(thread));
555a1d355fSStephan Aßmus	// put the new data
565a1d355fSStephan Aßmus	status_t error = fMap->Put(thread, data);
575a1d355fSStephan Aßmus	fMap->Unlock();
585a1d355fSStephan Aßmus	return error;
595a1d355fSStephan Aßmus}
605a1d355fSStephan Aßmus
615a1d355fSStephan Aßmus// Unset
625a1d355fSStephan Aßmusvoid
635a1d355fSStephan AßmusThreadLocal::Unset()
645a1d355fSStephan Aßmus{
655a1d355fSStephan Aßmus	if (!fMap)
665a1d355fSStephan Aßmus		return;
675a1d355fSStephan Aßmus	thread_id thread = find_thread(NULL);
685a1d355fSStephan Aßmus	fMap->Lock();
695a1d355fSStephan Aßmus	if (fFreeHandler) {
705a1d355fSStephan Aßmus		if (fMap->ContainsKey(thread))
715a1d355fSStephan Aßmus			fFreeHandler->Free(fMap->Remove(thread));
725a1d355fSStephan Aßmus	} else
735a1d355fSStephan Aßmus		fMap->Remove(thread);
745a1d355fSStephan Aßmus	fMap->Unlock();
755a1d355fSStephan Aßmus}
765a1d355fSStephan Aßmus
775a1d355fSStephan Aßmus// Get
785a1d355fSStephan Aßmusvoid*
795a1d355fSStephan AßmusThreadLocal::Get() const
805a1d355fSStephan Aßmus{
815a1d355fSStephan Aßmus	if (!fMap)
825a1d355fSStephan Aßmus		return NULL;
835a1d355fSStephan Aßmus	return fMap->Get(find_thread(NULL));
845a1d355fSStephan Aßmus}
855a1d355fSStephan Aßmus
86