|
|
|
@@ -23,15 +23,61 @@ |
|
|
|
==============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
static ThreadLocalValue<Thread*>& getCurrentThreadHolder()
|
|
|
|
|
|
|
|
Thread::Thread (const String& threadName_)
|
|
|
|
: threadName (threadName_),
|
|
|
|
threadHandle (nullptr),
|
|
|
|
threadId (0),
|
|
|
|
threadPriority (5),
|
|
|
|
affinityMask (0),
|
|
|
|
shouldExit (false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread::~Thread()
|
|
|
|
{
|
|
|
|
/* If your thread class's destructor has been called without first stopping the thread, that
|
|
|
|
means that this partially destructed object is still performing some work - and that's
|
|
|
|
probably a Bad Thing!
|
|
|
|
|
|
|
|
To avoid this type of nastiness, always make sure you call stopThread() before or during
|
|
|
|
your subclass's destructor.
|
|
|
|
*/
|
|
|
|
jassert (! isThreadRunning());
|
|
|
|
|
|
|
|
stopThread (100);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
// Use a ref-counted object to hold this shared data, so that it can outlive its static
|
|
|
|
// shared pointer when threads are still running during static shutdown.
|
|
|
|
struct CurrentThreadHolder : public ReferenceCountedObject
|
|
|
|
{
|
|
|
|
static ThreadLocalValue<Thread*> tls;
|
|
|
|
return tls;
|
|
|
|
CurrentThreadHolder() noexcept {}
|
|
|
|
|
|
|
|
typedef ReferenceCountedObjectPtr <CurrentThreadHolder> Ptr;
|
|
|
|
ThreadLocalValue<Thread*> value;
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE (CurrentThreadHolder);
|
|
|
|
};
|
|
|
|
|
|
|
|
static char currentThreadHolderLock [sizeof (SpinLock)]; // (statically initialised to zeros).
|
|
|
|
|
|
|
|
static CurrentThreadHolder::Ptr getCurrentThreadHolder()
|
|
|
|
{
|
|
|
|
static CurrentThreadHolder::Ptr currentThreadHolder;
|
|
|
|
SpinLock::ScopedLockType lock (*reinterpret_cast <SpinLock*> (currentThreadHolderLock));
|
|
|
|
|
|
|
|
if (currentThreadHolder == nullptr)
|
|
|
|
currentThreadHolder = new CurrentThreadHolder();
|
|
|
|
|
|
|
|
return currentThreadHolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Thread::threadEntryPoint()
|
|
|
|
{
|
|
|
|
getCurrentThreadHolder() = this;
|
|
|
|
const CurrentThreadHolder::Ptr currentThreadHolder (getCurrentThreadHolder());
|
|
|
|
currentThreadHolder->value = this;
|
|
|
|
|
|
|
|
JUCE_TRY
|
|
|
|
{
|
|
|
|
@@ -50,7 +96,7 @@ void Thread::threadEntryPoint() |
|
|
|
}
|
|
|
|
JUCE_CATCH_ALL_ASSERT
|
|
|
|
|
|
|
|
getCurrentThreadHolder().releaseCurrentThreadStorage();
|
|
|
|
currentThreadHolder->value.releaseCurrentThreadStorage();
|
|
|
|
closeThreadHandle();
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -60,31 +106,6 @@ void JUCE_API juce_threadEntryPoint (void* userData) |
|
|
|
static_cast <Thread*> (userData)->threadEntryPoint();
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
Thread::Thread (const String& threadName_)
|
|
|
|
: threadName (threadName_),
|
|
|
|
threadHandle (nullptr),
|
|
|
|
threadId (0),
|
|
|
|
threadPriority (5),
|
|
|
|
affinityMask (0),
|
|
|
|
shouldExit (false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread::~Thread()
|
|
|
|
{
|
|
|
|
/* If your thread class's destructor has been called without first stopping the thread, that
|
|
|
|
means that this partially destructed object is still performing some work - and that's
|
|
|
|
probably a Bad Thing!
|
|
|
|
|
|
|
|
To avoid this type of nastiness, always make sure you call stopThread() before or during
|
|
|
|
your subclass's destructor.
|
|
|
|
*/
|
|
|
|
jassert (! isThreadRunning());
|
|
|
|
|
|
|
|
stopThread (100);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void Thread::startThread()
|
|
|
|
{
|
|
|
|
@@ -120,6 +141,11 @@ bool Thread::isThreadRunning() const |
|
|
|
return threadHandle != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread* Thread::getCurrentThread()
|
|
|
|
{
|
|
|
|
return getCurrentThreadHolder()->value.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void Thread::signalThreadShouldExit()
|
|
|
|
{
|
|
|
|
@@ -211,12 +237,6 @@ void Thread::notify() const |
|
|
|
defaultEvent.signal();
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
Thread* Thread::getCurrentThread()
|
|
|
|
{
|
|
|
|
return *getCurrentThreadHolder();
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void SpinLock::enter() const noexcept
|
|
|
|
{
|
|
|
|
|