fixed theoretical issue when deferredGet onSize() methods destructs the underlying channel object

This commit is contained in:
Emiel Bruijntjes 2014-09-02 11:18:11 +02:00
parent 9653578d4a
commit 236dd02b13
2 changed files with 9 additions and 5 deletions

View File

@ -598,7 +598,7 @@ public:
Monitor monitor(this);
// copy the callback (so that it will not be destructed during
// the "reportSuccess" call
// the "reportSuccess" call, if the channel is destructed during the call)
auto cb = _oldestCallback;
// call the callback

View File

@ -27,10 +27,10 @@ const std::shared_ptr<Deferred> &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
@ -43,6 +43,10 @@ const std::shared_ptr<Deferred> &DeferredGet::reportSuccess(uint32_t messageCoun
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;
}