OpenShot Audio Library | OpenShotAudio  0.6.0
juce_MessageManager.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 MessageManagerLock;
27 class ThreadPoolJob;
28 class ActionListener;
29 class ActionBroadcaster;
30 
31 //==============================================================================
33 using MessageCallbackFunction = void* (void* userData);
34 
35 
36 //==============================================================================
44 class JUCE_API MessageManager final
45 {
46 public:
47  //==============================================================================
49  static MessageManager* getInstance();
50 
52  static MessageManager* getInstanceWithoutCreating() noexcept;
53 
57  static void deleteInstance();
58 
59  //==============================================================================
67  void runDispatchLoop();
68 
76  void stopDispatchLoop();
77 
80  bool hasStopMessageBeenSent() const noexcept { return quitMessagePosted.get() != 0; }
81 
82  #if JUCE_MODAL_LOOPS_PERMITTED
88  bool runDispatchLoopUntil (int millisecondsToRunFor);
89  #endif
90 
91  //==============================================================================
97  static bool callAsync (std::function<void()> functionToCall);
98 
117  void* callFunctionOnMessageThread (MessageCallbackFunction* callback, void* userData);
118 
120  bool isThisTheMessageThread() const noexcept;
121 
127  void setCurrentThreadAsMessageThread();
128 
134  Thread::ThreadID getCurrentMessageThread() const noexcept { return messageThreadId; }
135 
143  bool currentThreadHasLockedMessageManager() const noexcept;
144 
148  static bool existsAndIsLockedByCurrentThread() noexcept;
149 
153  static bool existsAndIsCurrentThread() noexcept;
154 
155  //==============================================================================
162  static void broadcastMessage (const String& messageText);
163 
171  void registerBroadcastListener (ActionListener* listener);
172 
174  void deregisterBroadcastListener (ActionListener* listener);
175 
176  //==============================================================================
181  class JUCE_API MessageBase : public ReferenceCountedObject
182  {
183  public:
184  MessageBase() = default;
185  ~MessageBase() override = default;
186 
187  virtual void messageCallback() = 0;
188  bool post();
189 
191 
192  JUCE_DECLARE_NON_COPYABLE (MessageBase)
193  };
194 
195  //==============================================================================
199  class JUCE_API Lock
200  {
201  public:
209  Lock();
210 
212  ~Lock();
213 
226  void enter() const noexcept;
227 
271  bool tryEnter() const noexcept;
272 
276  void exit() const noexcept;
277 
284  void abort() const noexcept;
285 
286  //==============================================================================
289 
292 
295 
296  private:
297  struct BlockingMessage;
298  friend class ReferenceCountedObjectPtr<BlockingMessage>;
299 
300  bool exclusiveTryAcquire (bool) const noexcept;
301  bool tryAcquire (bool) const noexcept;
302 
303  void setAcquired (bool success) const noexcept;
304 
305  //==============================================================================
306  // This mutex is used to make this lock type behave like a normal mutex.
307  // If multiple threads call enter() simultaneously, only one will succeed in gaining
308  // this mutex. The mutex is released again in exit().
309  mutable CriticalSection entryMutex;
310 
311  // This mutex protects the other data members of the lock from concurrent access, which
312  // happens when the BlockingMessage calls setAcquired to indicate that the lock was gained.
313  mutable std::mutex mutex;
314  mutable ReferenceCountedObjectPtr<BlockingMessage> blockingMessage;
315  mutable std::condition_variable condvar;
316  mutable bool abortWait = false, acquired = false;
317  };
318 
319  //==============================================================================
320  #ifndef DOXYGEN
321  // Internal methods - do not use!
322  void deliverBroadcastMessage (const String&);
323  ~MessageManager() noexcept;
324  #endif
325 
326 private:
327  //==============================================================================
328  MessageManager() noexcept;
329 
330  static MessageManager* instance;
331 
332  friend class MessageBase;
333  class QuitMessage;
334  friend class QuitMessage;
335  friend class MessageManagerLock;
336 
337  std::unique_ptr<ActionBroadcaster> broadcaster;
338  Atomic<int> quitMessagePosted { 0 }, quitMessageReceived { 0 };
339  Thread::ThreadID messageThreadId;
340  Atomic<Thread::ThreadID> threadWithLock;
341  mutable std::mutex messageThreadIdMutex;
342 
343  static bool postMessageToSystemQueue (MessageBase*);
344  static void* exitModalLoopCallback (void*);
345  static void doPlatformSpecificInitialisation();
346  static void doPlatformSpecificShutdown();
347 
348  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageManager)
349 };
350 
351 
352 //==============================================================================
389 class JUCE_API MessageManagerLock : private Thread::Listener
390 {
391 public:
392  //==============================================================================
434  MessageManagerLock (Thread* threadToCheckForExitSignal = nullptr);
435 
436  //==============================================================================
442  MessageManagerLock (ThreadPoolJob* jobToCheckForExitSignal);
443 
444  //==============================================================================
450  ~MessageManagerLock() override;
451 
452  //==============================================================================
456  bool lockWasGained() const noexcept { return locked; }
457 
458 private:
459  //==============================================================================
460  MessageManager::Lock mmLock;
461  bool locked;
462 
463  //==============================================================================
464  bool attemptLock (Thread*, ThreadPoolJob*);
465  void exitSignalSent() override;
466 
467  JUCE_DECLARE_NON_COPYABLE (MessageManagerLock)
468 };
469 
470 //==============================================================================
476 #define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED \
477  jassert (juce::MessageManager::existsAndIsLockedByCurrentThread());
478 
484 #define JUCE_ASSERT_MESSAGE_THREAD \
485  jassert (juce::MessageManager::existsAndIsCurrentThread());
486 
490 #define JUCE_ASSERT_MESSAGE_MANAGER_EXISTS \
491  jassert (juce::MessageManager::getInstanceWithoutCreating() != nullptr);
492 
493 
494 } // namespace juce
bool lockWasGained() const noexcept
bool hasStopMessageBeenSent() const noexcept
void * ThreadID
Definition: juce_Thread.h:477