diff --git a/modules/juce_core/native/juce_native_ThreadPriorities.h b/modules/juce_core/native/juce_native_ThreadPriorities.h index 5bc1d9e2c1..3af00464b0 100644 --- a/modules/juce_core/native/juce_native_ThreadPriorities.h +++ b/modules/juce_core/native/juce_native_ThreadPriorities.h @@ -62,7 +62,7 @@ struct ThreadPriorities { Thread::Priority::background, 0 }, #endif - #if JUCE_MAC | JUCE_IOS + #if JUCE_MAC || JUCE_IOS { Thread::Priority::highest, 4 }, { Thread::Priority::high, 3 }, { Thread::Priority::normal, 2 }, diff --git a/modules/juce_core/threads/juce_Thread.cpp b/modules/juce_core/threads/juce_Thread.cpp index 8d120235de..2c970bd2b0 100644 --- a/modules/juce_core/threads/juce_Thread.cpp +++ b/modules/juce_core/threads/juce_Thread.cpp @@ -302,7 +302,7 @@ void Thread::notify() const //============================================================================== struct LambdaThread : public Thread { - LambdaThread (std::function f) : Thread ("anonymous"), fn (f) {} + LambdaThread (std::function&& f) : Thread ("anonymous"), fn (std::move (f)) {} void run() override { @@ -315,11 +315,23 @@ struct LambdaThread : public Thread JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LambdaThread) }; -void Thread::launch (std::function functionToRun) +bool Thread::launch (std::function functionToRun) { - auto anon = new LambdaThread (functionToRun); + return launch (Priority::normal, std::move (functionToRun)); +} + +bool Thread::launch (Priority priority, std::function functionToRun) +{ + auto anon = std::make_unique (std::move (functionToRun)); anon->deleteOnThreadEnd = true; - anon->startThread(); + + if (anon->startThread (priority)) + { + anon.release(); + return true; + } + + return false; } //============================================================================== diff --git a/modules/juce_core/threads/juce_Thread.h b/modules/juce_core/threads/juce_Thread.h index 635daebc28..37fd6bf559 100644 --- a/modules/juce_core/threads/juce_Thread.h +++ b/modules/juce_core/threads/juce_Thread.h @@ -50,19 +50,19 @@ public: enum class Priority { /** The highest possible priority that isn't a dedicated realtime thread. */ - highest, + highest = 2, /** Makes use of performance cores and higher clocks. */ - high, + high = 1, /** The OS default. It will balance out across all cores. */ - normal, + normal = 0, /** Uses efficiency cores when possible. */ - low, + low = -1, /** Restricted to efficiency cores on platforms that have them. */ - background + background = -2 }; //============================================================================== @@ -187,7 +187,7 @@ public: bool stopThread (int timeOutMilliseconds); //============================================================================== - /** Invokes a lambda or function on its own thread. + /** Invokes a lambda or function on its own thread with the default priority. This will spin up a Thread object which calls the function and then exits. Bear in mind that starting and stopping a thread can be a fairly heavyweight @@ -197,8 +197,33 @@ public: Also note that using an anonymous thread makes it very difficult to interrupt the function when you need to stop it, e.g. when your app quits. So it's up to you to deal with situations where the function may fail to stop in time. + + @param functionToRun The lambda to be called from the new Thread. + + @returns true if the thread started successfully, or false if it failed. + + @see launch. */ - static void launch (std::function functionToRun); + static bool launch (std::function functionToRun); + + //============================================================================== + /** Invokes a lambda or function on its own thread with a custom priority. + + This will spin up a Thread object which calls the function and then exits. + Bear in mind that starting and stopping a thread can be a fairly heavyweight + operation, so you might prefer to use a ThreadPool if you're kicking off a lot + of short background tasks. + + Also note that using an anonymous thread makes it very difficult to interrupt + the function when you need to stop it, e.g. when your app quits. So it's up to + you to deal with situations where the function may fail to stop in time. + + @param priority The priority the thread is started with. + @param functionToRun The lambda to be called from the new Thread. + + @returns true if the thread started successfully, or false if it failed. + */ + static bool launch (Priority priority, std::function functionToRun); //============================================================================== /** Returns true if the thread is currently active */