1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Added some macros for asserting when functions are called in an unsafe manner outside the message thread.

This commit is contained in:
jules 2018-10-16 17:25:52 +01:00
parent 482d87e2db
commit 5979288706
29 changed files with 115 additions and 69 deletions

View file

@ -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)

View file

@ -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();

View file

@ -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();

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -78,7 +78,7 @@ struct AndroidMessageQueue : private Android::Runnable
~AndroidMessageQueue()
{
jassert (MessageManager::getInstance()->isThisTheMessageThread());
JUCE_ASSERT_MESSAGE_THREAD
clearSingletonInstance();
}

View file

@ -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);