26MessageManager::MessageManager() noexcept
27 : messageThreadId (Thread::getCurrentThreadId())
35MessageManager::~MessageManager() noexcept
39 doPlatformSpecificShutdown();
45MessageManager* MessageManager::instance =
nullptr;
49 if (instance ==
nullptr)
52 doPlatformSpecificInitialisation();
69bool MessageManager::MessageBase::post()
71 auto* mm = MessageManager::instance;
73 if (mm ==
nullptr || mm->quitMessagePosted.get() != 0 || ! postMessageToSystemQueue (
this))
83#if ! (JUCE_MAC || JUCE_IOS || JUCE_ANDROID)
87bool dispatchNextMessageOnSystemQueue (
bool returnIfNoPendingMessages);
95 void messageCallback()
override
97 if (
auto* mm = MessageManager::instance)
98 mm->quitMessageReceived =
true;
108 while (quitMessageReceived.
get() == 0)
112 if (! detail::dispatchNextMessageOnSystemQueue (
false))
122 quitMessagePosted =
true;
125#if JUCE_MODAL_LOOPS_PERMITTED
126bool MessageManager::runDispatchLoopUntil (
int millisecondsToRunFor)
132 while (quitMessageReceived.
get() == 0)
136 if (! detail::dispatchNextMessageOnSystemQueue (millisecondsToRunFor >= 0))
145 return quitMessageReceived.
get() == 0;
156 : func (f), parameter (param)
159 void messageCallback()
override
161 result = (*func) (parameter);
170 void*
const parameter;
178 return func (parameter);
187 message->finished.wait();
188 return message->result.load();
199 AsyncCallInvoker (
std::function<
void()> f) : callback (std::move (f)) {}
200 void messageCallback()
override { callback(); }
204 return (
new AsyncCallInvoker (std::move (fn)))->post();
208void MessageManager::deliverBroadcastMessage (
const String& value)
210 if (broadcaster !=
nullptr)
211 broadcaster->sendActionMessage (value);
216 if (broadcaster ==
nullptr)
219 broadcaster->addActionListener (listener);
224 if (broadcaster !=
nullptr)
225 broadcaster->removeActionListener (listener);
242 if (
std::exchange (messageThreadId, thisThread) != thisThread)
246 doPlatformSpecificShutdown();
247 doPlatformSpecificInitialisation();
255 return thisThread == messageThreadId || thisThread == threadWithLock.
get();
261 return i->currentThreadHasLockedMessageManager();
269 return i->isThisTheMessageThread();
290 void messageCallback()
override
294 if (owner !=
nullptr)
295 owner->setAcquired (
true);
297 condvar.wait (lock, [&] {
return owner ==
nullptr; });
302 const ScopeGuard scope { [&] { condvar.notify_one(); } };
322bool MessageManager::Lock::exclusiveTryAcquire (
bool lockIsMandatory)
const noexcept
326 else if (! entryMutex.tryEnter())
329 const auto result = tryAcquire (lockIsMandatory);
337bool MessageManager::Lock::tryAcquire (
bool lockIsMandatory)
const noexcept
339 auto* mm = MessageManager::instance;
347 if (! lockIsMandatory && [&]
356 if (mm->currentThreadHasLockedMessageManager())
361 blockingMessage = *
new BlockingMessage (
this);
369 if (! blockingMessage->post())
373 blockingMessage =
nullptr;
381 condvar.wait (lock, [&] {
return std::exchange (abortWait,
false); });
390 if (! lockIsMandatory)
396 blockingMessage->stopWaiting();
397 blockingMessage =
nullptr;
403 const auto wasAcquired = [&]
412 const ScopeGuard unlocker { [&] { entryMutex.exit(); } };
414 if (blockingMessage ==
nullptr)
417 if (
auto* mm = MessageManager::instance)
419 jassert (mm->currentThreadHasLockedMessageManager());
420 mm->threadWithLock = {};
423 blockingMessage->stopWaiting();
424 blockingMessage =
nullptr;
433void MessageManager::Lock::setAcquired (
bool x)
const noexcept
435 const ScopeGuard scope { [&] { condvar.notify_one(); } };
443 : locked (attemptLock (threadToCheck, nullptr))
447 : locked (attemptLock (nullptr, jobToCheck))
452 jassert (threadToCheck ==
nullptr || jobToCheck ==
nullptr);
454 if (threadToCheck !=
nullptr)
457 if (jobToCheck !=
nullptr)
462 && (jobToCheck ==
nullptr || ! jobToCheck->
shouldExit()))
468 if (threadToCheck !=
nullptr)
476 if (jobToCheck !=
nullptr)
489void MessageManagerLock::exitSignalSent()
512static int numScopedInitInstances = 0;
Manages a list of ActionListeners, and can send them messages.
Interface class for delivery of events that are sent by an ActionBroadcaster.
static void deleteAll()
Deletes all extant objects.
static bool isStandaloneApp() noexcept
Returns true if this executable is running as an app (as opposed to being a plugin or other kind of s...
~MessageManagerLock() override
Releases the current thread's lock on the message manager.
MessageManagerLock(Thread *threadToCheckForExitSignal=nullptr)
Tries to acquire a lock on the message manager.
A lock you can use to lock the message manager.
Lock()
Creates a new critical section to exclusively access methods which can only be called when the messag...
void enter() const noexcept
Acquires the message manager lock.
void abort() const noexcept
Unblocks a thread which is waiting in tryEnter Call this method if you want to unblock a thread which...
bool tryEnter() const noexcept
Attempts to lock the message manager and exits if abort is called.
void exit() const noexcept
Releases the message manager lock.
Internal class used as the base class for all message objects.
This class is in charge of the application's event-dispatch loop.
static bool callAsync(std::function< void()> functionToCall)
Asynchronously invokes a function or C++11 lambda on the message thread.
bool isThisTheMessageThread() const noexcept
Returns true if the caller-thread is the message thread.
static bool existsAndIsCurrentThread() noexcept
Returns true if there's an instance of the MessageManager, and if the current thread is running it.
void runDispatchLoop()
Runs the event dispatch loop until a stop message is posted.
void stopDispatchLoop()
Sends a signal that the dispatch loop should terminate.
bool currentThreadHasLockedMessageManager() const noexcept
Returns true if the caller thread has currently got the message manager locked.
void * callFunctionOnMessageThread(MessageCallbackFunction *callback, void *userData)
Calls a function using the message-thread.
void deregisterBroadcastListener(ActionListener *listener)
Deregisters a broadcast listener.
void setCurrentThreadAsMessageThread()
Called to tell the manager that the current thread is the one that's running the dispatch loop.
static bool existsAndIsLockedByCurrentThread() noexcept
Returns true if there's an instance of the MessageManager, and if the current thread has the lock on ...
void registerBroadcastListener(ActionListener *listener)
Registers a listener to get told about broadcast messages.
static void deleteInstance()
Deletes the global MessageManager instance.
static MessageManager * getInstanceWithoutCreating() noexcept
Returns the global instance of the MessageManager, or nullptr if it doesn't exist.
static MessageManager * getInstance()
Returns the global instance of the MessageManager.
A smart-pointer class which points to a reference-counted object.
~ScopedJuceInitialiser_GUI()
The destructor simply calls shutdownJuce_GUI().
ScopedJuceInitialiser_GUI()
The constructor simply calls initialiseJuce_GUI().
A task that is executed by a ThreadPool object.
void addListener(Thread::Listener *)
Add a listener to this thread job which will receive a callback when signalJobShouldExit was called o...
bool shouldExit() const noexcept
Returns true if something is trying to interrupt this job and make it stop.
void removeListener(Thread::Listener *)
Removes a listener added with addListener.
bool threadShouldExit() const
Checks whether the thread has been told to stop running.
static ThreadID JUCE_CALLTYPE getCurrentThreadId()
Returns an id that identifies the caller thread.
static void JUCE_CALLTYPE setCurrentThreadName(const String &newThreadName)
Changes the name of the caller thread.
void addListener(Listener *)
Add a listener to this thread which will receive a callback when signalThreadShouldExit was called on...
void removeListener(Listener *)
Removes a listener added with addListener.
static void JUCE_CALLTYPE sleep(int milliseconds)
Suspends the execution of the current thread until the specified timeout period has elapsed (note tha...
static int64 currentTimeMillis() noexcept
Returns the current system time.
Allows threads to wait for events triggered by other threads.
#define JUCE_TRY
The JUCE_TRY/JUCE_CATCH_EXCEPTION wrappers can be used to pass any uncaught exceptions to the JUCEApp...
#define JUCE_CATCH_EXCEPTION
The JUCE_TRY/JUCE_CATCH_EXCEPTION wrappers can be used to pass any uncaught exceptions to the JUCEApp...
#define JUCE_AUTORELEASEPOOL
A macro that can be used to easily declare a local ScopedAutoReleasePool object for RAII-based obj-C ...
void *(void *userData) MessageCallbackFunction
See MessageManager::callFunctionOnMessageThread() for use of this function type.
void deleteAndZero(Type &pointer)
Delete an object pointer, and sets the pointer to null.
JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI()
Clears up any static data being used by JUCE's GUI classes.
JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI()
Initialises JUCE's GUI classes.
Type get() const noexcept
Atomically reads and returns the current value.
An easy way to ensure that a function is called at the end of the current scope.