Browse Source

Fix for AsyncUpdaters.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
1a887cda63
6 changed files with 61 additions and 27 deletions
  1. +13
    -11
      juce_amalgamated.cpp
  2. +17
    -2
      juce_amalgamated.h
  3. +8
    -10
      src/events/juce_AsyncUpdater.cpp
  4. +4
    -2
      src/events/juce_AsyncUpdater.h
  5. +14
    -0
      src/events/juce_CallbackMessage.h
  6. +5
    -2
      src/events/juce_MessageManager.cpp

+ 13
- 11
juce_amalgamated.cpp View File

@@ -38422,6 +38422,7 @@ public:
AsyncUpdaterMessage (AsyncUpdater& owner_)
: owner (owner_)
{
setMessageIsDeletedOnDelivery (false);
}

void messageCallback()
@@ -38430,10 +38431,12 @@ public:
owner.handleAsyncUpdate();
}

private:
AsyncUpdater& owner;
};

AsyncUpdater::AsyncUpdater() throw()
AsyncUpdater::AsyncUpdater()
: message (new AsyncUpdaterMessage (*this))
{
}

@@ -38445,18 +38448,14 @@ AsyncUpdater::~AsyncUpdater()
// deleting this object, or find some other way to avoid such a race condition.
jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager());

pendingMessage = 0;
if (pendingMessage.exchange (0) != 0)
message.release()->setMessageIsDeletedOnDelivery (true);
}

void AsyncUpdater::triggerAsyncUpdate()
{
if (pendingMessage.value == 0)
{
ScopedPointer<AsyncUpdaterMessage> pending (new AsyncUpdaterMessage (*this));

if (pendingMessage.compareAndSetBool (pending, 0))
pending.release()->post();
}
if (pendingMessage.compareAndSetBool (message, 0))
message->post();
}

void AsyncUpdater::cancelPendingUpdate() throw()
@@ -39092,7 +39091,7 @@ void MessageManager::postMessageToQueue (Message* const message)
delete message;
}

CallbackMessage::CallbackMessage() throw() {}
CallbackMessage::CallbackMessage() throw() : deleteOnDelivery (true) {}
CallbackMessage::~CallbackMessage() {}

void CallbackMessage::post()
@@ -39106,7 +39105,7 @@ void MessageManager::deliverMessage (Message* const message)
{
JUCE_TRY
{
const ScopedPointer <Message> messageDeleter (message);
ScopedPointer <Message> messageDeleter (message);
MessageListener* const recipient = message->messageRecipient;

if (recipient == 0)
@@ -39116,6 +39115,9 @@ void MessageManager::deliverMessage (Message* const message)
if (callbackMessage != 0)
{
callbackMessage->messageCallback();

if (! callbackMessage->isMessageDeletedOnDelivery())
messageDeleter.release();
}
else if (message->intParameter1 == quitMessageId)
{


+ 17
- 2
juce_amalgamated.h View File

@@ -12490,7 +12490,7 @@ class JUCE_API AsyncUpdater
public:

/** Creates an AsyncUpdater object. */
AsyncUpdater() throw();
AsyncUpdater();

/** Destructor.

@@ -12544,7 +12544,8 @@ private:

class AsyncUpdaterMessage;
friend class AsyncUpdaterMessage;

friend class ScopedPointer<AsyncUpdaterMessage>;
ScopedPointer<AsyncUpdaterMessage> message;
Atomic<AsyncUpdaterMessage*> pendingMessage;
};

@@ -43823,8 +43824,22 @@ public:
*/
void post();

/** This can be used to indicate whether the MessageManager should delete the
message after it has been delivered.
By default, messages will be deleted, but you might want to disable this so that you
can re-use the same message.
*/
void setMessageIsDeletedOnDelivery (bool shouldBeDeleted) throw() { deleteOnDelivery = shouldBeDeleted; }

/** Returns true if the message should be deleted after is has been delivered.
@see setMessageIsDeletedOnDelivery
*/
bool isMessageDeletedOnDelivery() const throw() { return deleteOnDelivery; }

private:

bool deleteOnDelivery;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackMessage);
};



+ 8
- 10
src/events/juce_AsyncUpdater.cpp View File

@@ -29,7 +29,6 @@ BEGIN_JUCE_NAMESPACE
#include "juce_AsyncUpdater.h"
#include "juce_CallbackMessage.h"
#include "../containers/juce_ScopedPointer.h"
#include "juce_MessageManager.h"
@@ -40,6 +39,7 @@ public:
AsyncUpdaterMessage (AsyncUpdater& owner_)
: owner (owner_)
{
setMessageIsDeletedOnDelivery (false);
}
void messageCallback()
@@ -48,11 +48,13 @@ public:
owner.handleAsyncUpdate();
}
private:
AsyncUpdater& owner;
};
//==============================================================================
AsyncUpdater::AsyncUpdater() throw()
AsyncUpdater::AsyncUpdater()
: message (new AsyncUpdaterMessage (*this))
{
}
@@ -64,18 +66,14 @@ AsyncUpdater::~AsyncUpdater()
// deleting this object, or find some other way to avoid such a race condition.
jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager());
pendingMessage = 0;
if (pendingMessage.exchange (0) != 0)
message.release()->setMessageIsDeletedOnDelivery (true);
}
void AsyncUpdater::triggerAsyncUpdate()
{
if (pendingMessage.value == 0)
{
ScopedPointer<AsyncUpdaterMessage> pending (new AsyncUpdaterMessage (*this));
if (pendingMessage.compareAndSetBool (pending, 0))
pending.release()->post();
}
if (pendingMessage.compareAndSetBool (message, 0))
message->post();
}
void AsyncUpdater::cancelPendingUpdate() throw()


+ 4
- 2
src/events/juce_AsyncUpdater.h View File

@@ -27,6 +27,7 @@
#define __JUCE_ASYNCUPDATER_JUCEHEADER__
#include "../core/juce_Atomic.h"
#include "../containers/juce_ScopedPointer.h"
//==============================================================================
@@ -44,7 +45,7 @@ class JUCE_API AsyncUpdater
public:
//==============================================================================
/** Creates an AsyncUpdater object. */
AsyncUpdater() throw();
AsyncUpdater();
/** Destructor.
@@ -101,7 +102,8 @@ private:
//==============================================================================
class AsyncUpdaterMessage;
friend class AsyncUpdaterMessage;
friend class ScopedPointer<AsyncUpdaterMessage>;
ScopedPointer<AsyncUpdaterMessage> message;
Atomic<AsyncUpdaterMessage*> pendingMessage;
};


+ 14
- 0
src/events/juce_CallbackMessage.h View File

@@ -73,8 +73,22 @@ public:
*/
void post();
/** This can be used to indicate whether the MessageManager should delete the
message after it has been delivered.
By default, messages will be deleted, but you might want to disable this so that you
can re-use the same message.
*/
void setMessageIsDeletedOnDelivery (bool shouldBeDeleted) throw() { deleteOnDelivery = shouldBeDeleted; }
/** Returns true if the message should be deleted after is has been delivered.
@see setMessageIsDeletedOnDelivery
*/
bool isMessageDeletedOnDelivery() const throw() { return deleteOnDelivery; }
private:
//==============================================================================
bool deleteOnDelivery;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackMessage);
};


+ 5
- 2
src/events/juce_MessageManager.cpp View File

@@ -88,7 +88,7 @@ void MessageManager::postMessageToQueue (Message* const message)
}
//==============================================================================
CallbackMessage::CallbackMessage() throw() {}
CallbackMessage::CallbackMessage() throw() : deleteOnDelivery (true) {}
CallbackMessage::~CallbackMessage() {}
void CallbackMessage::post()
@@ -103,7 +103,7 @@ void MessageManager::deliverMessage (Message* const message)
{
JUCE_TRY
{
const ScopedPointer <Message> messageDeleter (message);
ScopedPointer <Message> messageDeleter (message);
MessageListener* const recipient = message->messageRecipient;
if (recipient == 0)
@@ -113,6 +113,9 @@ void MessageManager::deliverMessage (Message* const message)
if (callbackMessage != 0)
{
callbackMessage->messageCallback();
if (! callbackMessage->isMessageDeletedOnDelivery())
messageDeleter.release();
}
else if (message->intParameter1 == quitMessageId)
{


Loading…
Cancel
Save