diff --git a/include/amqpcpp/channelimpl.h b/include/amqpcpp/channelimpl.h index 963c337..da0c07c 100644 --- a/include/amqpcpp/channelimpl.h +++ b/include/amqpcpp/channelimpl.h @@ -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(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(); } diff --git a/include/amqpcpp/deferred.h b/include/amqpcpp/deferred.h index 89ed49e..c68ff78 100644 --- a/include/amqpcpp/deferred.h +++ b/include/amqpcpp/deferred.h @@ -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 diff --git a/src/channelimpl.cpp b/src/channelimpl.cpp index 60e6f7f..87508c9 100644 --- a/src/channelimpl.cpp +++ b/src/channelimpl.cpp @@ -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; }