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); Monitor monitor(this);
// copy the callback (so that it will not be destructed during // 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; auto cb = _oldestCallback;
// call the callback // 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 // we grab a self pointer to ensure that the deferred object stays alive
auto self = shared_from_this(); auto self = shared_from_this();
// report the size (technically, the channel object could be destructed now, but we ignore that case) // we now know the name, so we can install the message callback on the channel, the self
if (_sizeCallback) _sizeCallback(messageCount); // 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
// we now know the name, so we can install the message callback on the channel // is reported (onFinalize() is called from the destructor of this DeferredGet object)
_channel->install("", [self, this](const Message &message, uint64_t deliveryTag, bool redelivered) { _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 // install a monitor to deal with the case that the channel is removed
@ -42,6 +42,10 @@ const std::shared_ptr<Deferred> &DeferredGet::reportSuccess(uint32_t messageCoun
// we can remove the callback now from the channel // we can remove the callback now from the channel
if (monitor.valid()) _channel->uninstall(""); 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 object
return _next; return _next;