Loading...
Searching...
No Matches
juce_ThreadLocalValue.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
template <typename Type>
class ThreadLocalValue
{
public:
ThreadLocalValue() = default;
~ThreadLocalValue()
{
for (auto* o = first.get(); o != nullptr;)
{
auto* next = o->next;
delete o;
o = next;
}
}
Type& operator*() const noexcept { return get(); }
operator Type*() const noexcept { return &get(); }
Type* operator->() const noexcept { return &get(); }
ThreadLocalValue& operator= (const Type& newValue) { get() = newValue; return *this; }
Type& get() const noexcept
{
auto threadId = Thread::getCurrentThreadId();
ObjectHolder* o = nullptr;
for (o = first.get(); o != nullptr; o = o->next)
if (o->threadId.get() == threadId)
return o->object;
for (o = first.get(); o != nullptr; o = o->next)
if (o->threadId.compareAndSetBool (threadId, nullptr))
break;
if (o != nullptr)
o->object = Type();
else
for (o = new ObjectHolder (threadId, first.get());
! first.compareAndSetBool (o, o->next);
o->next = first.get());
return o->object;
}
void releaseCurrentThreadStorage()
{
auto threadId = Thread::getCurrentThreadId();
for (auto* o = first.get(); o != nullptr; o = o->next)
if (o->threadId.compareAndSetBool (nullptr, threadId))
return;
}
private:
//==============================================================================
struct ObjectHolder
{
ObjectHolder (Thread::ThreadID idToUse, ObjectHolder* n) : threadId (idToUse), next (n), object() {}
Atomic<Thread::ThreadID> threadId;
ObjectHolder* next;
Type object;
JUCE_DECLARE_NON_COPYABLE (ObjectHolder)
};
mutable Atomic<ObjectHolder*> first;
JUCE_DECLARE_NON_COPYABLE (ThreadLocalValue)
};
} // namespace juce
juce::ThreadLocalValue::operator*
Type & operator*() const noexcept
Definition juce_ThreadLocalValue.h:71
juce::ThreadLocalValue::operator->
Type * operator->() const noexcept
Definition juce_ThreadLocalValue.h:85
juce::ThreadLocalValue::releaseCurrentThreadStorage
void releaseCurrentThreadStorage()
Definition juce_ThreadLocalValue.h:121
juce::ThreadLocalValue::get
Type & get() const noexcept
Definition juce_ThreadLocalValue.h:95
juce::ThreadLocalValue::operator=
ThreadLocalValue & operator=(const Type &newValue)
Definition juce_ThreadLocalValue.h:88
juce::ThreadLocalValue::~ThreadLocalValue
~ThreadLocalValue()
Definition juce_ThreadLocalValue.h:56
juce::Thread::ThreadID
void * ThreadID
Definition juce_Thread.h:477
juce::Thread::getCurrentThreadId
static ThreadID JUCE_CALLTYPE getCurrentThreadId()
juce::Atomic::get
Type get() const noexcept
Definition juce_Atomic.h:64
juce::Atomic::compareAndSetBool
bool compareAndSetBool(Type newValue, Type valueToCompare) noexcept
Definition juce_Atomic.h:96