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 * that has a private constructor so that it can not be used from outside
* the AMQP library * the AMQP library
* *
* @copyright 2014 - 2018 Copernica BV * @copyright 2014 - 2020 Copernica BV
*/ */
/** /**
@ -658,8 +658,13 @@ public:
// call the callback // call the callback
auto next = cb->reportSuccess(std::forward<Arguments>(parameters)...); 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; 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 // set the oldest callback
_oldestCallback = next; _oldestCallback = next;
@ -729,8 +734,8 @@ public:
DeferredPublisher *publisher() const { return _publisher.get(); } DeferredPublisher *publisher() const { return _publisher.get(); }
/** /**
* Retrieve the deferred confirm that handles publisher confirms * Retrieve the deferred confirm that handles publisher confirms
* @return The deferred confirm object * @return The deferred confirm object
*/ */
DeferredConfirm *confirm() const { return _confirm.get(); } DeferredConfirm *confirm() const { return _confirm.get(); }

View File

@ -5,7 +5,7 @@
* possibly happen in the future that can be * possibly happen in the future that can be
* caught. * caught.
* *
* @copyright 2014 - 2018 Copernica BV * @copyright 2014 - 2020 Copernica BV
*/ */
/** /**
@ -178,6 +178,15 @@ protected:
// store pointer // store pointer
_next = deferred; _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 * The channel implementation may call our

View File

@ -3,7 +3,7 @@
* *
* Implementation for a channel * Implementation for a channel
* *
* @copyright 2014 - 2018 Copernica BV * @copyright 2014 - 2020 Copernica BV
*/ */
#include "includes.h" #include "includes.h"
#include "basicgetokframe.h" #include "basicgetokframe.h"
@ -816,6 +816,11 @@ void ChannelImpl::reportError(const char *message, bool notifyhandler)
// leap out if channel no longer exists // leap out if channel no longer exists
if (!monitor.valid()) return; 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 // set the oldest callback
_oldestCallback = next; _oldestCallback = next;
} }
@ -833,6 +838,11 @@ void ChannelImpl::reportError(const char *message, bool notifyhandler)
// leap out if channel no longer exists // leap out if channel no longer exists
if (!monitor.valid()) return; 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 // set the oldest callback
_oldestCallback = next; _oldestCallback = next;
} }