| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2020 - 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
 - {
 - 
 - //==============================================================================
 - /**
 -     Provides cross-platform support for thread-local objects.
 - 
 -     This class holds an internal list of objects of the templated type, keeping
 -     an instance for each thread that requests one. The first time a thread attempts
 -     to access its value, an object is created and added to the list for that thread.
 - 
 -     Typically, you'll probably want to create a static instance of a ThreadLocalValue
 -     object, or hold one within a singleton.
 - 
 -     The templated class for your value must be a primitive type, or a simple POD struct.
 - 
 -     When a thread no longer needs to use its value, it can call releaseCurrentThreadStorage()
 -     to allow the storage to be re-used by another thread. If a thread exits without calling
 -     this method, the object storage will be left allocated until the ThreadLocalValue object
 -     is deleted.
 - 
 -     @tags{Core}
 - */
 - template <typename Type>
 - class ThreadLocalValue
 - {
 - public:
 -     /** */
 -     ThreadLocalValue() = default;
 - 
 -     /** Destructor.
 -         When this object is deleted, all the value objects for all threads will be deleted.
 -     */
 -     ~ThreadLocalValue()
 -     {
 -         for (auto* o = first.get(); o != nullptr;)
 -         {
 -             auto* next = o->next;
 -             delete o;
 -             o = next;
 -         }
 -     }
 - 
 -     /** Returns a reference to this thread's instance of the value.
 -         Note that the first time a thread tries to access the value, an instance of the
 -         value object will be created - so if your value's class has a non-trivial
 -         constructor, be aware that this method could invoke it.
 -     */
 -     Type& operator*() const noexcept                        { return get(); }
 - 
 -     /** Returns a pointer to this thread's instance of the value.
 -         Note that the first time a thread tries to access the value, an instance of the
 -         value object will be created - so if your value's class has a non-trivial
 -         constructor, be aware that this method could invoke it.
 -     */
 -     operator Type*() const noexcept                         { return &get(); }
 - 
 -     /** Accesses a method or field of the value object.
 -         Note that the first time a thread tries to access the value, an instance of the
 -         value object will be created - so if your value's class has a non-trivial
 -         constructor, be aware that this method could invoke it.
 -     */
 -     Type* operator->() const noexcept                       { return &get(); }
 - 
 -     /** Assigns a new value to the thread-local object. */
 -     ThreadLocalValue& operator= (const Type& newValue)      { get() = newValue; return *this; }
 - 
 -     /** Returns a reference to this thread's instance of the value.
 -         Note that the first time a thread tries to access the value, an instance of the
 -         value object will be created - so if your value's class has a non-trivial
 -         constructor, be aware that this method could invoke it.
 -     */
 -     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;
 -     }
 - 
 -     /** Called by a thread before it terminates, to allow this class to release
 -         any storage associated with the thread.
 -     */
 -     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
 
 
  |