From c0e262463dca50f32f8ee0f74a2a60185620990f Mon Sep 17 00:00:00 2001 From: jules Date: Sun, 9 Feb 2014 17:10:13 +0000 Subject: [PATCH] Added method ThreadPoolJob::getCurrentThreadPoolJob() --- modules/juce_core/threads/juce_ThreadPool.cpp | 122 +++++++++--------- modules/juce_core/threads/juce_ThreadPool.h | 9 +- 2 files changed, 71 insertions(+), 60 deletions(-) diff --git a/modules/juce_core/threads/juce_ThreadPool.cpp b/modules/juce_core/threads/juce_ThreadPool.cpp index 257572a541..e6b0b9f9ad 100644 --- a/modules/juce_core/threads/juce_ThreadPool.cpp +++ b/modules/juce_core/threads/juce_ThreadPool.cpp @@ -26,12 +26,31 @@ ============================================================================== */ +class ThreadPool::ThreadPoolThread : public Thread +{ +public: + ThreadPoolThread (ThreadPool& p) + : Thread ("Pool"), currentJob (nullptr), pool (p) + { + } + + void run() override + { + while (! threadShouldExit()) + if (! pool.runNextJob (*this)) + wait (500); + } + + ThreadPoolJob* volatile currentJob; + ThreadPool& pool; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolThread) +}; + +//============================================================================== ThreadPoolJob::ThreadPoolJob (const String& name) - : jobName (name), - pool (nullptr), - shouldStop (false), - isActive (false), - shouldBeDeleted (false) + : jobName (name), pool (nullptr), + shouldStop (false), isActive (false), shouldBeDeleted (false) { } @@ -57,30 +76,13 @@ void ThreadPoolJob::signalJobShouldExit() shouldStop = true; } -//============================================================================== -class ThreadPool::ThreadPoolThread : public Thread +ThreadPoolJob* ThreadPoolJob::getCurrentThreadPoolJob() { -public: - ThreadPoolThread (ThreadPool& pool_) - : Thread ("Pool"), - pool (pool_) - { - } + if (ThreadPool::ThreadPoolThread* t = dynamic_cast (Thread::getCurrentThread())) + return t->currentJob; - void run() override - { - while (! threadShouldExit()) - { - if (! pool.runNextJob()) - wait (500); - } - } - -private: - ThreadPool& pool; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolThread) -}; + return nullptr; +} //============================================================================== ThreadPool::ThreadPool (const int numThreads) @@ -164,8 +166,7 @@ bool ThreadPool::isJobRunning (const ThreadPoolJob* const job) const return jobs.contains (const_cast (job)) && job->isActive; } -bool ThreadPool::waitForJobToFinish (const ThreadPoolJob* const job, - const int timeOutMs) const +bool ThreadPool::waitForJobToFinish (const ThreadPoolJob* const job, const int timeOutMs) const { if (job != nullptr) { @@ -215,7 +216,7 @@ bool ThreadPool::removeJob (ThreadPoolJob* const job, } bool ThreadPool::removeAllJobs (const bool interruptRunningJobs, const int timeOutMs, - ThreadPool::JobSelector* selectedJobsToRemove) + ThreadPool::JobSelector* const selectedJobsToRemove) { Array jobsToWaitFor; @@ -328,46 +329,49 @@ ThreadPoolJob* ThreadPool::pickNextJobToRun() return nullptr; } -bool ThreadPool::runNextJob() +bool ThreadPool::runNextJob (ThreadPoolThread& thread) { - ThreadPoolJob* const job = pickNextJobToRun(); - - if (job == nullptr) - return false; - - ThreadPoolJob::JobStatus result = ThreadPoolJob::jobHasFinished; - - JUCE_TRY + if (ThreadPoolJob* const job = pickNextJobToRun()) { - result = job->runJob(); - } - JUCE_CATCH_ALL_ASSERT + ThreadPoolJob::JobStatus result = ThreadPoolJob::jobHasFinished; + thread.currentJob = job; - OwnedArray deletionList; - - { - const ScopedLock sl (lock); - - if (jobs.contains (job)) + JUCE_TRY { - job->isActive = false; + result = job->runJob(); + } + JUCE_CATCH_ALL_ASSERT - if (result != ThreadPoolJob::jobNeedsRunningAgain || job->shouldStop) - { - jobs.removeFirstMatchingValue (job); - addToDeleteList (deletionList, job); + thread.currentJob = nullptr; - jobFinishedSignal.signal(); - } - else + OwnedArray deletionList; + + { + const ScopedLock sl (lock); + + if (jobs.contains (job)) { - // move the job to the end of the queue if it wants another go - jobs.move (jobs.indexOf (job), -1); + job->isActive = false; + + if (result != ThreadPoolJob::jobNeedsRunningAgain || job->shouldStop) + { + jobs.removeFirstMatchingValue (job); + addToDeleteList (deletionList, job); + + jobFinishedSignal.signal(); + } + else + { + // move the job to the end of the queue if it wants another go + jobs.move (jobs.indexOf (job), -1); + } } } + + return true; } - return true; + return false; } void ThreadPool::addToDeleteList (OwnedArray& deletionList, ThreadPoolJob* const job) const diff --git a/modules/juce_core/threads/juce_ThreadPool.h b/modules/juce_core/threads/juce_ThreadPool.h index ed820e8065..3d5f7622bb 100644 --- a/modules/juce_core/threads/juce_ThreadPool.h +++ b/modules/juce_core/threads/juce_ThreadPool.h @@ -119,6 +119,12 @@ public: */ void signalJobShouldExit(); + //============================================================================== + /** If the calling thread is being invoked inside a runJob() method, this will + return the ThreadPoolJob that it belongs to. + */ + static ThreadPoolJob* getCurrentThreadPoolJob(); + //============================================================================== private: friend class ThreadPool; @@ -290,6 +296,7 @@ private: Array jobs; class ThreadPoolThread; + friend class ThreadPoolJob; friend class ThreadPoolThread; friend struct ContainerDeletePolicy; OwnedArray threads; @@ -297,7 +304,7 @@ private: CriticalSection lock; WaitableEvent jobFinishedSignal; - bool runNextJob(); + bool runNextJob (ThreadPoolThread&); ThreadPoolJob* pickNextJobToRun(); void addToDeleteList (OwnedArray&, ThreadPoolJob*) const; void createThreads (int numThreads);