OpenShot Audio Library | OpenShotAudio  0.6.0
juce_Thread.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 //==============================================================================
42 class JUCE_API Thread
43 {
44 public:
45  //==============================================================================
46  static constexpr size_t osDefaultStackSize { 0 };
47 
48  //==============================================================================
53  enum class Priority
54  {
56  highest = 2,
57 
59  high = 1,
60 
62  normal = 0,
63 
65  low = -1,
66 
68  background = -2
69  };
70 
71  //==============================================================================
77  {
84  [[nodiscard]] RealtimeOptions withPriority (int newPriority) const
85  {
86  jassert (isPositiveAndNotGreaterThan (newPriority, 10));
87  return withMember (*this, &RealtimeOptions::priority, juce::jlimit (0, 10, newPriority));
88  }
89 
96  [[nodiscard]] RealtimeOptions withProcessingTimeMs (double newProcessingTimeMs) const
97  {
98  jassert (newProcessingTimeMs > 0.0);
99  return withMember (*this, &RealtimeOptions::processingTimeMs, newProcessingTimeMs);
100  }
101 
108  [[nodiscard]] RealtimeOptions withMaximumProcessingTimeMs (double newMaximumProcessingTimeMs) const
109  {
110  jassert (newMaximumProcessingTimeMs > 0.0);
111  return withMember (*this, &RealtimeOptions::maximumProcessingTimeMs, newMaximumProcessingTimeMs);
112  }
113 
124  [[nodiscard]] RealtimeOptions withApproximateAudioProcessingTime (int samplesPerFrame, double sampleRate) const
125  {
126  jassert (samplesPerFrame > 0);
127  jassert (sampleRate > 0.0);
128 
129  const auto approxFrameTimeMs = (samplesPerFrame / sampleRate) * 1000.0;
130  return withMaximumProcessingTimeMs (approxFrameTimeMs);
131  }
132 
141  [[nodiscard]] RealtimeOptions withPeriodMs (double newPeriodMs) const
142  {
143  jassert (newPeriodMs > 0.0);
144  return withMember (*this, &RealtimeOptions::periodMs, newPeriodMs);
145  }
146 
155  [[nodiscard]] RealtimeOptions withPeriodHz (double newPeriodHz) const
156  {
157  jassert (newPeriodHz > 0.0);
158  return withPeriodMs (1'000.0 / newPeriodHz);
159  }
160 
165  [[nodiscard]] int getPriority() const
166  {
167  return priority;
168  }
169 
175  [[nodiscard]] std::optional<double> getProcessingTimeMs() const
176  {
177  return processingTimeMs;
178  }
179 
185  [[nodiscard]] std::optional<double> getMaximumProcessingTimeMs() const
186  {
187  return maximumProcessingTimeMs;
188  }
189 
195  [[nodiscard]] std::optional<double> getPeriodMs() const
196  {
197  return periodMs;
198  }
199 
200  private:
201  int priority { 5 };
202  std::optional<double> processingTimeMs;
203  std::optional<double> maximumProcessingTimeMs;
204  std::optional<double> periodMs{};
205  };
206 
207  //==============================================================================
220  explicit Thread (const String& threadName, size_t threadStackSize = osDefaultStackSize);
221 
229  virtual ~Thread();
230 
231  //==============================================================================
240  virtual void run() = 0;
241 
242  //==============================================================================
256  bool startThread();
257 
274  bool startThread (Priority newPriority);
275 
287  bool startRealtimeThread (const RealtimeOptions& options);
288 
309  bool stopThread (int timeOutMilliseconds);
310 
311  //==============================================================================
329  static bool launch (std::function<void()> functionToRun);
330 
331  //==============================================================================
348  static bool launch (Priority priority, std::function<void()> functionToRun);
349 
350  //==============================================================================
352  bool isThreadRunning() const;
353 
365  void signalThreadShouldExit();
366 
374  bool threadShouldExit() const;
375 
382  static bool currentThreadShouldExit();
383 
391  bool waitForThreadToExit (int timeOutMilliseconds) const;
392 
393  //==============================================================================
395  class JUCE_API Listener
396  {
397  public:
398  virtual ~Listener() = default;
399 
403  virtual void exitSignalSent() = 0;
404  };
405 
411  void addListener (Listener*);
412 
414  void removeListener (Listener*);
415 
417  bool isRealtime() const;
418 
419  //==============================================================================
427  void setAffinityMask (uint32 affinityMask);
428 
435  static void JUCE_CALLTYPE setCurrentThreadAffinityMask (uint32 affinityMask);
436 
437  //==============================================================================
445  static void JUCE_CALLTYPE sleep (int milliseconds);
446 
452  static void JUCE_CALLTYPE yield();
453 
454  //==============================================================================
462  bool wait (double timeOutMilliseconds) const;
463 
470  void notify() const;
471 
472  //==============================================================================
477  using ThreadID = void*;
478 
486  static ThreadID JUCE_CALLTYPE getCurrentThreadId();
487 
493  static Thread* JUCE_CALLTYPE getCurrentThread();
494 
503  ThreadID getThreadId() const noexcept;
504 
506  const String& getThreadName() const noexcept { return threadName; }
507 
512  static void JUCE_CALLTYPE setCurrentThreadName (const String& newThreadName);
513 
514  #if JUCE_ANDROID || DOXYGEN
515  //==============================================================================
553  static void initialiseJUCE (void* jniEnv, void* jContext);
554  #endif
555 
556 protected:
557  //==============================================================================
566 
579  bool setPriority (Priority newPriority);
580 
581 private:
582  //==============================================================================
583  const String threadName;
584  std::atomic<void*> threadHandle { nullptr };
585  std::atomic<ThreadID> threadId { nullptr };
586  std::optional<RealtimeOptions> realtimeOptions = {};
587  CriticalSection startStopLock;
588  WaitableEvent startSuspensionEvent, defaultEvent;
589  size_t threadStackSize;
590  uint32 affinityMask = 0;
591  bool deleteOnThreadEnd = false;
592  std::atomic<bool> shouldExit { false };
593  ListenerList<Listener, Array<Listener*, CriticalSection>> listeners;
594 
595  #if JUCE_ANDROID || JUCE_LINUX || JUCE_BSD
596  std::atomic<Priority> priority;
597  #endif
598 
599  #ifndef DOXYGEN
600  friend void JUCE_API juce_threadEntryPoint (void*);
601  #endif
602 
603  bool startThreadInternal (Priority);
604  bool createNativeThread (Priority);
605  void closeThreadHandle();
606  void killThread();
607  void threadEntryPoint();
608 
609  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Thread)
610 };
611 
612 } // namespace juce
virtual void exitSignalSent()=0
static void JUCE_CALLTYPE setCurrentThreadAffinityMask(uint32 affinityMask)
void * ThreadID
Definition: juce_Thread.h:477
static void JUCE_CALLTYPE sleep(int milliseconds)
Priority getPriority() const
static void JUCE_CALLTYPE setCurrentThreadName(const String &newThreadName)
bool setPriority(Priority newPriority)
virtual void run()=0
static void JUCE_CALLTYPE yield()
static ThreadID JUCE_CALLTYPE getCurrentThreadId()
RealtimeOptions withPeriodHz(double newPeriodHz) const
Definition: juce_Thread.h:155
RealtimeOptions withPeriodMs(double newPeriodMs) const
Definition: juce_Thread.h:141
RealtimeOptions withMaximumProcessingTimeMs(double newMaximumProcessingTimeMs) const
Definition: juce_Thread.h:108
RealtimeOptions withApproximateAudioProcessingTime(int samplesPerFrame, double sampleRate) const
Definition: juce_Thread.h:124
std::optional< double > getPeriodMs() const
Definition: juce_Thread.h:195
std::optional< double > getMaximumProcessingTimeMs() const
Definition: juce_Thread.h:185
RealtimeOptions withPriority(int newPriority) const
Definition: juce_Thread.h:84
std::optional< double > getProcessingTimeMs() const
Definition: juce_Thread.h:175
RealtimeOptions withProcessingTimeMs(double newProcessingTimeMs) const
Definition: juce_Thread.h:96