From 236dd02b136c42b50622acb012d48e0705e127a1 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Tue, 2 Sep 2014 11:18:11 +0200 Subject: [PATCH] fixed theoretical issue when deferredGet onSize() methods destructs the underlying channel object --- include/channelimpl.h | 2 +- src/deferredget.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/channelimpl.h b/include/channelimpl.h index 56f1e753..409e259e 100644 --- a/include/channelimpl.h +++ b/include/channelimpl.h @@ -598,7 +598,7 @@ class ChannelImpl : public Watchable, public std::enable_shared_from_this &DeferredGet::reportSuccess(uint32_t messageCoun // we grab a self pointer to ensure that the deferred object stays alive auto self = shared_from_this(); - // report the size (technically, the channel object could be destructed now, but we ignore that case) - if (_sizeCallback) _sizeCallback(messageCount); - - // we now know the name, so we can install the message callback on the channel + // we now know the name, so we can install the message callback on the channel, the self + // pointer is also captured, which ensures that 'this' is not destructed, all members stay + // accessible, and that the onFinalize() function will only be called after the message + // is reported (onFinalize() is called from the destructor of this DeferredGet object) _channel->install("", [self, this](const Message &message, uint64_t deliveryTag, bool redelivered) { // install a monitor to deal with the case that the channel is removed @@ -42,6 +42,10 @@ const std::shared_ptr &DeferredGet::reportSuccess(uint32_t messageCoun // we can remove the callback now from the channel if (monitor.valid()) _channel->uninstall(""); }); + + // report the size (note that this is the size _minus_ the message that is retrieved + // (and for which the callback will be called later), so it could be zero) + if (_sizeCallback) _sizeCallback(messageCount); // return next object return _next;