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:
parent
482d87e2db
commit
5979288706
29 changed files with 115 additions and 69 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ struct AndroidMessageQueue : private Android::Runnable
|
|||
|
||||
~AndroidMessageQueue()
|
||||
{
|
||||
jassert (MessageManager::getInstance()->isThisTheMessageThread());
|
||||
JUCE_ASSERT_MESSAGE_THREAD
|
||||
clearSingletonInstance();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue