From 5979288706b8df23fc6577ef7f4978f0041b7c93 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 16 Oct 2018 17:25:52 +0100 Subject: [PATCH] Added some macros for asserting when functions are called in an unsafe manner outside the message thread. --- .../Licenses/jucer_LicenseController.cpp | 4 +-- .../Source/Licenses/jucer_LicenseThread.h | 2 +- .../LiveBuildEngine/jucer_ActivityList.h | 2 +- .../Source/LiveBuildEngine/jucer_ErrorList.h | 2 +- .../native/juce_mac_CoreMidi.cpp | 4 +-- .../AU/juce_AUv3_Wrapper.mm | 8 ++--- .../format/juce_AudioPluginFormat.cpp | 2 +- .../format_types/juce_VST3PluginFormat.cpp | 4 +-- .../format_types/juce_VSTPluginFormat.cpp | 4 +-- .../gui/juce_AudioThumbnail.cpp | 2 +- .../topology/juce_PhysicalTopologySource.cpp | 3 -- .../broadcasters/juce_ActionBroadcaster.cpp | 4 +-- .../broadcasters/juce_AsyncUpdater.cpp | 4 +-- .../broadcasters/juce_ChangeBroadcaster.cpp | 8 ++--- .../messages/juce_MessageListener.cpp | 2 +- .../messages/juce_MessageManager.cpp | 16 +++++++++ .../messages/juce_MessageManager.h | 34 ++++++++++++++++++ .../native/juce_android_Messaging.cpp | 2 +- modules/juce_events/timers/juce_Timer.cpp | 2 +- .../juce_ApplicationCommandManager.cpp | 2 +- .../components/juce_Component.cpp | 36 ++++++++++--------- .../components/juce_ModalComponentManager.cpp | 2 +- .../juce_gui_basics/desktop/juce_Desktop.cpp | 10 +++--- .../juce_gui_basics/desktop/juce_Displays.cpp | 6 ++-- modules/juce_gui_basics/juce_gui_basics.cpp | 9 +++-- .../native/juce_android_Windowing.cpp | 2 +- .../native/juce_linux_X11_Windowing.cpp | 4 +-- .../native/juce_win32_Windowing.cpp | 2 +- .../windows/juce_ThreadWithProgressWindow.cpp | 2 +- 29 files changed, 115 insertions(+), 69 deletions(-) diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp index 9ab293743a..681a0263fb 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp +++ b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp @@ -153,7 +153,7 @@ void LicenseController::startWebviewIfNeeded() void LicenseController::logout() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED #if ! JUCER_ENABLE_GPL_MODE thread.reset(); @@ -169,7 +169,7 @@ void LicenseController::logout() void LicenseController::chooseNewLicense() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED #if ! JUCER_ENABLE_GPL_MODE thread.reset(); diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseThread.h b/extras/Projucer/Source/Licenses/jucer_LicenseThread.h index 9c1e1f20b4..8d5febaf3c 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseThread.h +++ b/extras/Projucer/Source/Licenses/jucer_LicenseThread.h @@ -35,7 +35,7 @@ struct NetWorkerThread : public Thread, ~NetWorkerThread() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED signalThreadShouldExit(); cancelPendingUpdate(); diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h index 097f7f798a..90efe24296 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h @@ -105,7 +105,7 @@ private: static void checkThread() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActivityList) diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h b/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h index 60cfe34ecf..21878217db 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h @@ -114,7 +114,7 @@ private: static void checkThread() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ErrorList) diff --git a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp index 355f196529..ec48fdf793 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp @@ -222,7 +222,7 @@ namespace CoreMidiHelpers { // It seems that OSX can be a bit picky about the thread that's first used to // search for devices. It's safest to use the message thread for calling this. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD StringArray s; enableSimulatorMidiSession(); @@ -268,7 +268,7 @@ namespace CoreMidiHelpers { // Since OSX 10.6, the MIDIClientCreate function will only work // correctly when called from the message thread! - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD enableSimulatorMidiSession(); diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index afc7c66e32..54b04ffd15 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -1740,15 +1740,13 @@ public: JuceAUViewController (AUViewController* p) : myself (p) { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); - PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_AudioUnitv3; initialiseJuce_GUI(); } ~JuceAUViewController() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD if (processorHolder != nullptr) JuceAudioUnitv3::removeEditor (getAudioProcessor()); @@ -1757,7 +1755,7 @@ public: //============================================================================== void loadView() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD if (AudioProcessor* p = createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3)) { @@ -1894,7 +1892,7 @@ private: //============================================================================== AUAudioUnit* createAudioUnitOnMessageThread (const AudioComponentDescription& descr, NSError** error) { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD [myself view]; // this will call [view load] and ensure that the AudioProcessor has been instantiated diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp index 88a3eb3197..c16bafeeaf 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp @@ -199,7 +199,7 @@ void AudioPluginFormat::createPluginInstanceOnMessageThread (const PluginDescrip AudioPluginFormat::InstantiationCompletionCallback* callback) { jassert (callback != nullptr); - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD //============================================================================== diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 1913ef8011..fda384f3f2 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -1536,7 +1536,7 @@ struct VST3ComponentHolder // On Windows it's highly advisable to create your plugins using the message thread, // because many plugins need a chance to create HWNDs that will get their messages // delivered by the main message thread, and that's not possible from a background thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD #endif factory = ComSmartPtr (module->getPluginFactory()); @@ -1749,7 +1749,7 @@ public: // On Windows it's highly advisable to create your plugins using the message thread, // because many plugins need a chance to create HWNDs that will get their messages // delivered by the main message thread, and that's not possible from a background thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD #endif if (! holder->initialise()) diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index c61d6a15f7..c0f11b6d3e 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -1210,7 +1210,7 @@ struct VSTPluginInstance : public AudioPluginInstance, // because many plugins need a chance to create HWNDs that will get their // messages delivered by the main message thread, and that's not possible from // a background thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD #endif JUCE_VST_LOG ("Initialising VST: " + vstModule->pluginName + " (" + getVersion() + ")"); @@ -3216,7 +3216,7 @@ private: { // You shouldn't end up hitting this assertion unless the host is trying to do GUI // cleanup on a non-GUI thread.. If it does that, bad things could happen in here.. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED JUCE_VST_LOG ("Closing VST UI: " + plugin.getName()); isOpen = false; diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp index 9ad264c296..85bdca3d73 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp @@ -642,7 +642,7 @@ void AudioThumbnail::saveTo (OutputStream& output) const //============================================================================== bool AudioThumbnail::setDataSource (LevelDataSource* newSource) { - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED numSamplesFinished = 0; diff --git a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp index 0280f2861e..f2803e5996 100644 --- a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp +++ b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp @@ -23,9 +23,6 @@ namespace juce { -#define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED \ - jassert (juce::MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - #if DUMP_BANDWIDTH_STATS namespace { diff --git a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp index d495ebedef..7112a8116a 100644 --- a/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp @@ -52,13 +52,13 @@ private: ActionBroadcaster::ActionBroadcaster() { // are you trying to create this object before or after juce has been intialised?? - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); + JUCE_ASSERT_MESSAGE_MANAGER_EXISTS } ActionBroadcaster::~ActionBroadcaster() { // all event-based objects must be deleted BEFORE juce is shut down! - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); + JUCE_ASSERT_MESSAGE_MANAGER_EXISTS } void ActionBroadcaster::addActionListener (ActionListener* const listener) diff --git a/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp b/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp index b745f5f8c2..66795e476b 100644 --- a/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp +++ b/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp @@ -63,7 +63,7 @@ void AsyncUpdater::triggerAsyncUpdate() { // If you're calling this before (or after) the MessageManager is // running, then you're not going to get any callbacks! - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); + JUCE_ASSERT_MESSAGE_MANAGER_EXISTS if (activeMessage->shouldDeliver.compareAndSetBool (1, 0)) if (! activeMessage->post()) @@ -79,7 +79,7 @@ void AsyncUpdater::cancelPendingUpdate() noexcept void AsyncUpdater::handleUpdateNowIfNeeded() { // This can only be called by the event thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (activeMessage->shouldDeliver.exchange (0) != 0) handleAsyncUpdate(); diff --git a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp index 5b7298a2b5..0b8941c79d 100644 --- a/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp +++ b/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp @@ -36,7 +36,7 @@ void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) { // Listeners can only be safely added when the event thread is locked // You can use a MessageManagerLock if you need to call this from another thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED changeListeners.add (listener); } @@ -45,7 +45,7 @@ void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) { // Listeners can only be safely removed when the event thread is locked // You can use a MessageManagerLock if you need to call this from another thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED changeListeners.remove (listener); } @@ -54,7 +54,7 @@ void ChangeBroadcaster::removeAllChangeListeners() { // Listeners can only be safely removed when the event thread is locked // You can use a MessageManagerLock if you need to call this from another thread. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED changeListeners.clear(); } @@ -68,7 +68,7 @@ void ChangeBroadcaster::sendChangeMessage() void ChangeBroadcaster::sendSynchronousChangeMessage() { // This can only be called by the event thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED broadcastCallback.cancelPendingUpdate(); callListeners(); diff --git a/modules/juce_events/messages/juce_MessageListener.cpp b/modules/juce_events/messages/juce_MessageListener.cpp index 741122d963..78f18aa2d7 100644 --- a/modules/juce_events/messages/juce_MessageListener.cpp +++ b/modules/juce_events/messages/juce_MessageListener.cpp @@ -35,7 +35,7 @@ void Message::messageCallback() MessageListener::MessageListener() noexcept { // Are you trying to create a messagelistener before or after juce has been intialised?? - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); + JUCE_ASSERT_MESSAGE_MANAGER_EXISTS } MessageListener::~MessageListener() diff --git a/modules/juce_events/messages/juce_MessageManager.cpp b/modules/juce_events/messages/juce_MessageManager.cpp index 13cf34d5d5..81ecbba31f 100644 --- a/modules/juce_events/messages/juce_MessageManager.cpp +++ b/modules/juce_events/messages/juce_MessageManager.cpp @@ -231,6 +231,22 @@ bool MessageManager::currentThreadHasLockedMessageManager() const noexcept return thisThread == messageThreadId || thisThread == threadWithLock.get(); } +bool MessageManager::existsAndIsLockedByCurrentThread() noexcept +{ + if (auto i = getInstanceWithoutCreating()) + return i->currentThreadHasLockedMessageManager(); + + return false; +} + +bool MessageManager::existsAndIsCurrentThread() noexcept +{ + if (auto i = getInstanceWithoutCreating()) + return i->isThisTheMessageThread(); + + return false; +} + //============================================================================== //============================================================================== /* The only safe way to lock the message thread while another thread does diff --git a/modules/juce_events/messages/juce_MessageManager.h b/modules/juce_events/messages/juce_MessageManager.h index 51d8090d62..4518cb4066 100644 --- a/modules/juce_events/messages/juce_MessageManager.h +++ b/modules/juce_events/messages/juce_MessageManager.h @@ -147,6 +147,16 @@ public: */ bool currentThreadHasLockedMessageManager() const noexcept; + /** Returns true if there's an instance of the MessageManager, and if the current thread + has the lock on it. + */ + static bool existsAndIsLockedByCurrentThread() noexcept; + + /** Returns true if there's an instance of the MessageManager, and if the current thread + is running it. + */ + static bool existsAndIsCurrentThread() noexcept; + //============================================================================== /** Sends a message to all other JUCE applications that are running. @@ -462,4 +472,28 @@ private: JUCE_DECLARE_NON_COPYABLE (MessageManagerLock) }; +//============================================================================== +/** This macro is used to catch unsafe use of functions which expect to only be called + on the message thread, or when a MessageManagerLock is in place. + It will also fail if you try to use the function before the message manager has been + created, which could happen if you accidentally invoke it during a static constructor. +*/ +#define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED \ + jassert (juce::MessageManager::existsAndIsLockedByCurrentThread()); + +/** This macro is used to catch unsafe use of functions which expect to only be called + on the message thread. + It will also fail if you try to use the function before the message manager has been + created, which could happen if you accidentally invoke it during a static constructor. +*/ +#define JUCE_ASSERT_MESSAGE_THREAD \ + jassert (juce::MessageManager::existsAndIsCurrentThread()); + +/** This macro is used to catch unsafe use of functions which expect to not be called + outside the lifetime of the MessageManager. +*/ +#define JUCE_ASSERT_MESSAGE_MANAGER_EXISTS \ + jassert (juce::MessageManager::getInstanceWithoutCreating() != nullptr); + + } // namespace juce diff --git a/modules/juce_events/native/juce_android_Messaging.cpp b/modules/juce_events/native/juce_android_Messaging.cpp index abc5e6bcee..0088e1e7b7 100644 --- a/modules/juce_events/native/juce_android_Messaging.cpp +++ b/modules/juce_events/native/juce_android_Messaging.cpp @@ -78,7 +78,7 @@ struct AndroidMessageQueue : private Android::Runnable ~AndroidMessageQueue() { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD clearSingletonInstance(); } diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp index f2e280d1e6..a989c89b0d 100644 --- a/modules/juce_events/timers/juce_Timer.cpp +++ b/modules/juce_events/timers/juce_Timer.cpp @@ -324,7 +324,7 @@ void Timer::startTimer (int interval) noexcept { // If you're calling this before (or after) the MessageManager is // running, then you're not going to get any timer callbacks! - jassert (MessageManager::getInstanceWithoutCreating() != nullptr); + JUCE_ASSERT_MESSAGE_MANAGER_EXISTS const TimerThread::LockType::ScopedLockType sl (TimerThread::lock); diff --git a/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp b/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp index 0723261782..50674ea337 100644 --- a/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp +++ b/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp @@ -185,7 +185,7 @@ bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::Invocati { // This call isn't thread-safe for use from a non-UI thread without locking the message // manager first.. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED bool ok = false; ApplicationCommandInfo commandInfo (0); diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 48cf59f876..c0daeb417f 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -456,7 +456,7 @@ void Component::setName (const String& name) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN if (componentName != name) { @@ -482,7 +482,7 @@ void Component::setVisible (bool shouldBeVisible) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN const WeakReference safePointer (this); flags.visibleFlag = shouldBeVisible; @@ -562,7 +562,7 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (isOpaque()) styleWanted &= ~ComponentPeer::windowIsSemiTransparent; @@ -663,7 +663,7 @@ void Component::removeFromDesktop() { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN if (flags.hasHeavyweightPeerFlag) { @@ -839,7 +839,7 @@ void Component::toFront (bool setAsForeground) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN if (flags.hasHeavyweightPeerFlag) { @@ -1030,7 +1030,7 @@ void Component::setBounds (int x, int y, int w, int h) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN if (w < 0) w = 0; if (h < 0) h = 0; @@ -1344,7 +1344,7 @@ void Component::addChildComponent (Component& child, int zOrder) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN jassert (this != &child); // adding a component to itself!? @@ -1422,7 +1422,7 @@ Component* Component::removeChildComponent (int index, bool sendParentEvents, bo { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN auto* child = childComponentList [index]; @@ -1609,7 +1609,7 @@ void Component::enterModalState (bool shouldTakeKeyboardFocus, { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (! isCurrentlyModal (false)) { @@ -1786,7 +1786,7 @@ void Component::internalRepaintUnchecked (Rectangle area, bool isEntireComp { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (flags.visibleFlag) { @@ -2166,10 +2166,12 @@ void Component::addComponentListener (ComponentListener* newListener) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS + #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS if (getParentComponent() != nullptr) - ASSERT_MESSAGE_MANAGER_IS_LOCKED; - #endif + { + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED + } + #endif componentListeners.add (newListener); } @@ -2220,7 +2222,7 @@ void Component::addMouseListener (MouseListener* newListener, { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED // If you register a component as a mouselistener for itself, it'll receive all the events // twice - once via the direct callback that all components get anyway, and then again as a listener! @@ -2236,7 +2238,7 @@ void Component::removeMouseListener (MouseListener* listenerToRemove) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (mouseListeners != nullptr) mouseListeners->removeListener (listenerToRemove); @@ -2736,7 +2738,7 @@ void Component::grabKeyboardFocus() { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED grabFocusInternal (focusChangedDirectly, true); @@ -2751,7 +2753,7 @@ void Component::moveKeyboardFocusToSibling (bool moveToNext) { // if component methods are being called from threads other than the message // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (parentComponent != nullptr) { diff --git a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp index ce5e1ac71e..94865c3b96 100644 --- a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp +++ b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp @@ -254,7 +254,7 @@ bool ModalComponentManager::cancelAllModalComponents() int ModalComponentManager::runEventLoopForCurrentComponent() { // This can only be run from the message thread! - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD int returnValue = 0; diff --git a/modules/juce_gui_basics/desktop/juce_Desktop.cpp b/modules/juce_gui_basics/desktop/juce_Desktop.cpp index 829559bc49..3cfb54e6b7 100644 --- a/modules/juce_gui_basics/desktop/juce_Desktop.cpp +++ b/modules/juce_gui_basics/desktop/juce_Desktop.cpp @@ -70,7 +70,7 @@ Component* Desktop::getComponent (int index) const noexcept Component* Desktop::findComponentAt (Point screenPosition) const { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED for (int i = desktopComponents.size(); --i >= 0;) { @@ -105,7 +105,7 @@ LookAndFeel& Desktop::getDefaultLookAndFeel() noexcept void Desktop::setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED currentLookAndFeel = newDefaultLookAndFeel; for (int i = getNumComponents(); --i >= 0;) @@ -216,14 +216,14 @@ ListenerList& Desktop::getMouseListeners() void Desktop::addGlobalMouseListener (MouseListener* listener) { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED mouseListeners.add (listener); resetTimer(); } void Desktop::removeGlobalMouseListener (MouseListener* listener) { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED mouseListeners.remove (listener); resetTimer(); } @@ -323,7 +323,7 @@ bool Desktop::isOrientationEnabled (DisplayOrientation orientation) const noexce void Desktop::setGlobalScaleFactor (float newScaleFactor) noexcept { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED if (masterScaleFactor != newScaleFactor) { diff --git a/modules/juce_gui_basics/desktop/juce_Displays.cpp b/modules/juce_gui_basics/desktop/juce_Displays.cpp index 2465ef9062..7ef4a32ce8 100644 --- a/modules/juce_gui_basics/desktop/juce_Displays.cpp +++ b/modules/juce_gui_basics/desktop/juce_Displays.cpp @@ -138,7 +138,7 @@ Point Displays::logicalToPhysical (Point point, const Disp const Displays::Display& Displays::getMainDisplay() const noexcept { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED for (auto& d : displays) if (d.isMain) @@ -151,7 +151,7 @@ const Displays::Display& Displays::getMainDisplay() const noexcept RectangleList Displays::getRectangleList (bool userAreasOnly) const { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED RectangleList rl; for (auto& d : displays) @@ -197,7 +197,7 @@ bool operator!= (const Displays::Display& d1, const Displays::Display& d2) noexc // Deprecated method const Displays::Display& Displays::getDisplayContaining (Point position) const noexcept { - ASSERT_MESSAGE_MANAGER_IS_LOCKED + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED auto* best = &displays.getReference (0); auto bestDistance = std::numeric_limits::max(); diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 6a7ca43031..3c98769a84 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -139,11 +139,10 @@ #include //============================================================================== -#define ASSERT_MESSAGE_MANAGER_IS_LOCKED \ - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - -#define ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN \ - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager() || getPeer() == nullptr); +#define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN \ + jassert ((MessageManager::getInstanceWithoutCreating() != nullptr \ + && MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager()) \ + || getPeer() == nullptr); namespace juce { diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 8dd08f50ef..b7c1562a86 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -74,7 +74,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* en jassertfalse; // you must supply an application object for an android app! } - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD } JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* env, jobject)) diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp index 03689bdf67..ab9b9496b9 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp @@ -1051,7 +1051,7 @@ public: isAlwaysOnTop (comp.isAlwaysOnTop()) { // it's dangerous to create a window on a thread other than the message thread.. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED display = XWindowSystem::getInstance()->displayRef(); @@ -1097,7 +1097,7 @@ public: ~LinuxComponentPeer() { // it's dangerous to delete a window on a thread other than the message thread.. - jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED #if JUCE_X11_SUPPORTS_XEMBED juce_handleXEmbedEvent (this, nullptr); diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index cf7a1ed834..70985e653d 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -1275,7 +1275,7 @@ public: void setTitle (const String& title) override { // Unfortunately some ancient bits of win32 mean you can only perform this operation from the message thread. - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD SetWindowText (hwnd, title.toWideCharPointer()); } diff --git a/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp b/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp index cf6358cbad..346ae7d42e 100644 --- a/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp @@ -59,7 +59,7 @@ ThreadWithProgressWindow::~ThreadWithProgressWindow() void ThreadWithProgressWindow::launchThread (int priority) { - jassert (MessageManager::getInstance()->isThisTheMessageThread()); + JUCE_ASSERT_MESSAGE_THREAD startThread (priority); startTimer (100);