deferred-chain was in kept in scope by a consumer-operation, this fixes #323

This commit is contained in:
Emiel Bruijntjes 2020-02-28 12:45:45 +01:00
parent a2e4beb2a9
commit f3ba779e67
3 changed files with 30 additions and 6 deletions

View File

@ -5,7 +5,7 @@
* that has a private constructor so that it can not be used from outside
* the AMQP library
*
* @copyright 2014 - 2018 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -658,8 +658,13 @@ public:
// call the callback
auto next = cb->reportSuccess(std::forward<Arguments>(parameters)...);
// leap out if channel no longer exists
// leap out if channel no longer exist
if (!monitor.valid()) return false;
// in case the callback-shared-pointer is still kept in scope (for example because it
// is stored in the list of consumers), we do want to ensure that it no longer maintains
// a chain of queued deferred objects
cb->unchain();
// set the oldest callback
_oldestCallback = next;
@ -729,8 +734,8 @@ public:
DeferredPublisher *publisher() const { return _publisher.get(); }
/**
* Retrieve the deferred confirm that handles publisher confirms
* @return The deferred confirm object
* Retrieve the deferred confirm that handles publisher confirms
* @return The deferred confirm object
*/
DeferredConfirm *confirm() const { return _confirm.get(); }

View File

@ -5,7 +5,7 @@
* possibly happen in the future that can be
* caught.
*
* @copyright 2014 - 2018 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
/**
@ -178,6 +178,15 @@ protected:
// store pointer
_next = deferred;
}
/**
* Remove this object from the chain of deferreds
*/
void unchain()
{
// we no longer need the next pointer
_next = nullptr;
}
/**
* The channel implementation may call our

View File

@ -3,7 +3,7 @@
*
* Implementation for a channel
*
* @copyright 2014 - 2018 Copernica BV
* @copyright 2014 - 2020 Copernica BV
*/
#include "includes.h"
#include "basicgetokframe.h"
@ -816,6 +816,11 @@ void ChannelImpl::reportError(const char *message, bool notifyhandler)
// leap out if channel no longer exists
if (!monitor.valid()) return;
// in case the callback-shared-pointer is still kept in scope (for example because it
// is stored in the list of consumers), we do want to ensure that it no longer maintains
// a chain of queued deferred objects
cb->unchain();
// set the oldest callback
_oldestCallback = next;
}
@ -833,6 +838,11 @@ void ChannelImpl::reportError(const char *message, bool notifyhandler)
// leap out if channel no longer exists
if (!monitor.valid()) return;
// in case the callback-shared-pointer is still kept in scope (for example because it
// is stored in the list of consumers), we do want to ensure that it no longer maintains
// a chain of queued deferred objects
cb->unchain();
// set the oldest callback
_oldestCallback = next;
}