I have a ThreadPoolJob that I am using for cache management. The need for management arrives asynchronously, and I do not want to consume threadpool time by leaving the job in the pool. So when activity arrives, I reschedule it (::addJob). The issue arises if the ThreadPoolJob is already running, and I have new work for it. There is a race.
If the job is exiting, whether it has asked to be rescheduled or not, the ‘active’ flag will be cleared. The ‘pool’ pointer may or may not be cleared.
The only observable state for the job is ‘active’ via the ::isActive method. And so my rescheduling code can not avoid occasionally hitting the assert at L132 in ThreadPool::addJob.
My solution is either to comment out this assert - and accept that I am calling ‘::addJob’ when it may be unnecessary or make the state I really need to see (ThreadPoolJob::pool) is observable.
My solution is to add ThreadPoolJob::isScheduled
juce_ThreadPool.h L100
/** Returns true if this job is currently attached to a thread pool. */
bool isScheduled() const noexcept { return (pool != nullptr); }
This avoids the nuisance assert and ensures that that ::addJob is only called if it is necessary. There is however still a race that will have rescheduling being missed when there is new work for the ThreadPoolJob to do, and the ThreadPoolJob has already exited and is yet to be removed from the thread pool (ThreadPoolJob::pool assigned to nullptr).
So - I think there may be a higher level design issue that this case exposes; that a ThreadPoolJob of this type (reschedulable) itself may not know that it is done when it finishes running due to asynchronous activity in another thread. In this case a better solution may be a ThreadPool::ensureReschedule call that guarantees the specified ThreadPoolJob is not removed from the pool before it has had one more kick of the can through its ::runJob method.
For my purposes - the ::isScheduled call is a minimally intrusive fix. The proposed ::ensureReschedule mechanism needs a bit more thought and more extensive changes.
Curious to hear other thoughts on this.
