OpenShot Audio Library | OpenShotAudio  0.6.0
juce_ThreadPool.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 class ThreadPool;
27 
28 //==============================================================================
44 class JUCE_API ThreadPoolJob
45 {
46 public:
47  //==============================================================================
51  explicit ThreadPoolJob (const String& name);
52 
54  virtual ~ThreadPoolJob();
55 
56  //==============================================================================
60  String getJobName() const;
61 
65  void setJobName (const String& newName);
66 
67  //==============================================================================
70  enum JobStatus
71  {
72  jobHasFinished = 0,
75  jobNeedsRunningAgain
77  };
78 
93  virtual JobStatus runJob() = 0;
94 
95 
96  //==============================================================================
98  bool isRunning() const noexcept { return isActive; }
99 
107  bool shouldExit() const noexcept { return shouldStop; }
108 
114  void signalJobShouldExit();
115 
121  void addListener (Thread::Listener*);
122 
124  void removeListener (Thread::Listener*);
125 
126  //==============================================================================
130  static ThreadPoolJob* getCurrentThreadPoolJob();
131 
132  //==============================================================================
133 private:
134  friend class ThreadPool;
135  String jobName;
136  ThreadPool* pool = nullptr;
137  std::atomic<bool> shouldStop { false }, isActive { false }, shouldBeDeleted { false };
138  ListenerList<Thread::Listener, Array<Thread::Listener*, CriticalSection>> listeners;
139 
140  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolJob)
141 };
142 
143 //==============================================================================
155 {
157  [[nodiscard]] ThreadPoolOptions withThreadName (String newThreadName) const
158  {
159  return withMember (*this, &ThreadPoolOptions::threadName, newThreadName);
160  }
161 
165  [[nodiscard]] ThreadPoolOptions withNumberOfThreads (int newNumberOfThreads) const
166  {
167  return withMember (*this, &ThreadPoolOptions::numberOfThreads, newNumberOfThreads);
168  }
169 
171  [[nodiscard]] ThreadPoolOptions withThreadStackSizeBytes (size_t newThreadStackSizeBytes) const
172  {
173  return withMember (*this, &ThreadPoolOptions::threadStackSizeBytes, newThreadStackSizeBytes);
174  }
175 
177  [[nodiscard]] ThreadPoolOptions withDesiredThreadPriority (Thread::Priority newDesiredThreadPriority) const
178  {
179  return withMember (*this, &ThreadPoolOptions::desiredThreadPriority, newDesiredThreadPriority);
180  }
181 
182  String threadName { "Pool" };
183  int numberOfThreads { SystemStats::getNumCpus() };
184  size_t threadStackSizeBytes { Thread::osDefaultStackSize };
185  Thread::Priority desiredThreadPriority { Thread::Priority::normal };
186 };
187 
188 
189 //==============================================================================
200 class JUCE_API ThreadPool
201 {
202 public:
203  using Options = ThreadPoolOptions;
204 
205  //==============================================================================
211  explicit ThreadPool (const Options& options);
212 
221 
232  ThreadPool (int numberOfThreads,
233  size_t threadStackSizeBytes = Thread::osDefaultStackSize,
234  Thread::Priority desiredThreadPriority = Thread::Priority::normal);
235 
242  ~ThreadPool();
243 
244  //==============================================================================
249  class JUCE_API JobSelector
250  {
251  public:
252  virtual ~JobSelector() = default;
253 
259  virtual bool isJobSuitable (ThreadPoolJob* job) = 0;
260  };
261 
262  //==============================================================================
278  void addJob (ThreadPoolJob* job,
279  bool deleteJobWhenFinished);
280 
284  void addJob (std::function<ThreadPoolJob::JobStatus()> job);
285 
289  void addJob (std::function<void()> job);
290 
308  bool removeJob (ThreadPoolJob* job,
309  bool interruptIfRunning,
310  int timeOutMilliseconds);
311 
323  bool removeAllJobs (bool interruptRunningJobs,
324  int timeOutMilliseconds,
325  JobSelector* selectedJobsToRemove = nullptr);
326 
328  int getNumJobs() const noexcept;
329 
331  int getNumThreads() const noexcept;
332 
338  ThreadPoolJob* getJob (int index) const noexcept;
339 
344  bool contains (const ThreadPoolJob* job) const noexcept;
345 
347  bool isJobRunning (const ThreadPoolJob* job) const noexcept;
348 
357  bool waitForJobToFinish (const ThreadPoolJob* job,
358  int timeOutMilliseconds) const;
359 
363  void moveJobToFront (const ThreadPoolJob* jobToMove) noexcept;
364 
368  StringArray getNamesOfAllJobs (bool onlyReturnActiveJobs) const;
369 
370 private:
371  //==============================================================================
372  Array<ThreadPoolJob*> jobs;
373 
374  struct ThreadPoolThread;
375  friend class ThreadPoolJob;
376  OwnedArray<ThreadPoolThread> threads;
377 
378  CriticalSection lock;
379  WaitableEvent jobFinishedSignal;
380 
381  bool runNextJob (ThreadPoolThread&);
382  ThreadPoolJob* pickNextJobToRun();
383  void addToDeleteList (OwnedArray<ThreadPoolJob>&, ThreadPoolJob*) const;
384  void stopThreads();
385 
386  // Note that this method has changed, and no longer has a parameter to indicate
387  // whether the jobs should be deleted - see the new method for details.
388  void removeAllJobs (bool, int, bool);
389 
390  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPool)
391 };
392 
393 } // namespace juce
static int getNumCpus() noexcept
bool isRunning() const noexcept
bool shouldExit() const noexcept
virtual JobStatus runJob()=0
virtual bool isJobSuitable(ThreadPoolJob *job)=0
ThreadPoolOptions withThreadName(String newThreadName) const
ThreadPoolOptions withNumberOfThreads(int newNumberOfThreads) const
ThreadPoolOptions withDesiredThreadPriority(Thread::Priority newDesiredThreadPriority) const
ThreadPoolOptions withThreadStackSizeBytes(size_t newThreadStackSizeBytes) const