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_) AsyncUpdaterMessage (AsyncUpdater& owner_)
: owner (owner_) : owner (owner_)
{ {
setMessageIsDeletedOnDelivery (false);
} }


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


private:
AsyncUpdater& owner; 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. // deleting this object, or find some other way to avoid such a race condition.
jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager());


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


void AsyncUpdater::triggerAsyncUpdate() 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() void AsyncUpdater::cancelPendingUpdate() throw()
@@ -39092,7 +39091,7 @@ void MessageManager::postMessageToQueue (Message* const message)
delete message; delete message;
} }


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


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


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

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


+ 17
- 2
juce_amalgamated.h View File

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


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


/** Destructor. /** Destructor.


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


class AsyncUpdaterMessage; class AsyncUpdaterMessage;
friend class AsyncUpdaterMessage; friend class AsyncUpdaterMessage;

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


@@ -43823,8 +43824,22 @@ public:
*/ */
void post(); 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: private:


bool deleteOnDelivery;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackMessage); 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_AsyncUpdater.h"
#include "juce_CallbackMessage.h" #include "juce_CallbackMessage.h"
#include "../containers/juce_ScopedPointer.h"
#include "juce_MessageManager.h" #include "juce_MessageManager.h"
@@ -40,6 +39,7 @@ public:
AsyncUpdaterMessage (AsyncUpdater& owner_) AsyncUpdaterMessage (AsyncUpdater& owner_)
: owner (owner_) : owner (owner_)
{ {
setMessageIsDeletedOnDelivery (false);
} }
void messageCallback() void messageCallback()
@@ -48,11 +48,13 @@ public:
owner.handleAsyncUpdate(); owner.handleAsyncUpdate();
} }
private:
AsyncUpdater& owner; 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. // deleting this object, or find some other way to avoid such a race condition.
jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager());
pendingMessage = 0;
if (pendingMessage.exchange (0) != 0)
message.release()->setMessageIsDeletedOnDelivery (true);
} }
void AsyncUpdater::triggerAsyncUpdate() 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() void AsyncUpdater::cancelPendingUpdate() throw()


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

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


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

@@ -73,8 +73,22 @@ public:
*/ */
void post(); 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: private:
//============================================================================== //==============================================================================
bool deleteOnDelivery;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackMessage); 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() {} CallbackMessage::~CallbackMessage() {}
void CallbackMessage::post() void CallbackMessage::post()
@@ -103,7 +103,7 @@ void MessageManager::deliverMessage (Message* const message)
{ {
JUCE_TRY JUCE_TRY
{ {
const ScopedPointer <Message> messageDeleter (message);
ScopedPointer <Message> messageDeleter (message);
MessageListener* const recipient = message->messageRecipient; MessageListener* const recipient = message->messageRecipient;
if (recipient == 0) if (recipient == 0)
@@ -113,6 +113,9 @@ void MessageManager::deliverMessage (Message* const message)
if (callbackMessage != 0) if (callbackMessage != 0)
{ {
callbackMessage->messageCallback(); callbackMessage->messageCallback();
if (! callbackMessage->isMessageDeletedOnDelivery())
messageDeleter.release();
} }
else if (message->intParameter1 == quitMessageId) else if (message->intParameter1 == quitMessageId)
{ {


Loading…
Cancel
Save