Skip to content

Commit

Permalink
fixed theoretical issue when deferredGet onSize() methods destructs t…
Browse files Browse the repository at this point in the history
…he underlying channel object
  • Loading branch information
EmielBruijntjes committed Sep 2, 2014
1 parent 9653578 commit 236dd02
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 5 deletions.
2 changes: 1 addition & 1 deletion include/channelimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ class ChannelImpl : public Watchable, public std::enable_shared_from_this<Channe
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
Expand Down
12 changes: 8 additions & 4 deletions src/deferredget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -42,6 +42,10 @@ const std::shared_ptr<Deferred> &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;
Expand Down

0 comments on commit 236dd02

Please sign in to comment.