Cleaning up running ThreadPoolJobs

Slightly different than my previous post about ThreadPoolJobs and statically allocated objects, I’ve run into the following situation.

  • I’ve got an object that manages a ThreadPool and some ThreadPoolJobs

  • The destructor of that object cleans up all the running threads

  • The runJob() method of the various ThreadPoolJobs periodically checks ThreadPoolJob::shouldExit()

shutdownJuce_NonGUI calls Thread::stopAllThreads which makes Thread::threadShouldExit return true. But, from my ThreadPoolJob child classes, I don’t see a way to access that value. The return value from ThreadPoolJob::shouldExit doesn’t change even after the calls to Thread::threadShouldExit.

In an app that calls shutdownJuce_NonGUI before the end of main and statically allocates an instance of that object, the assert in Thread::stopThread fires if one of the ThreadPoolJobs is still running.

Does it make sense to create something similar to the filewide-static runningThreads (juce_Thread.cpp) in juce_ThreadPool.cpp, with a new method similar to like Thread::stopAllThreads? Then shutdownJuce_NonGUI could call that new method and I think the ThreadPoolJobs would cleanly exit.


Threads and thread-pools shouldn’t still be running when it hits the shutdownJuce_NonGUI code - Thread::stopAllThreads is just in there as a last resort in case something has gone wrong.

You just need to clean up your object properly before the app quits. Maybe simply use DeletedAtShutdown?

I suppose I could. I’d rather not force users of my code to allocate objects in a particular way though.

The code is all in place to clean itself up properly otherwise. The destructor of the statically allocated object does just that…unfortunately after shutdownJuce_NonGUI.

Eek… How could statically destructed objects possibly work in an event-driven or multi-threaded app? No chance! There are so many ways that could go wrong, it doesn’t even bear thinking about!