Skip to content

Commit

Permalink
mqb: fix ClientSession::initiateShutdown crash (bloomberg#349)
Browse files Browse the repository at this point in the history
Signed-off-by: dorjesinpo <129227380+dorjesinpo@users.noreply.github.com>
  • Loading branch information
dorjesinpo authored and alexander-e1off committed Oct 24, 2024
1 parent 0b0f30f commit 8c9b078
Showing 1 changed file with 35 additions and 10 deletions.
45 changes: 35 additions & 10 deletions src/groups/mqb/mqba/mqba_clientsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2816,16 +2816,41 @@ void ClientSession::initiateShutdown(const ShutdownCb& callback,

BALL_LOG_INFO << description() << ": initiateShutdown";

dispatcher()->execute(
bdlf::BindUtil::bind(
bdlf::MemFnUtil::memFn(&ClientSession::initiateShutdownDispatched,
d_self.acquire()),
callback,
timeout),
this,
mqbi::DispatcherEventType::e_DISPATCHER);
// Use 'mqbi::DispatcherEventType::e_DISPATCHER' to avoid (re)enabling
// 'd_flushList'
// The 'd_self.acquire()' return 'shared_ptr<ClientSession>' but that does
// not relate to the 'shared_ptr<mqbnet::Session>' acquired by
// 'mqbnet::TransportManagerIterator'. The latter is bound to the
// 'initiateShutdown'. The former can be null after 'd_self.invalidate()'
// call. ('invalidate()' waits for all _acquired_ 'shared_ptr' references
// to drop).
//
// We have a choice, either 1) bind the latter to 'initiateShutdown' to
// make sure 'd_self.acquire()' returns not null, or 2) invoke the
// 'callback' earlier if fail to 'acquire()' because of 'invalidate()', or
// 3) bind _acquired_ 'shared_ptr' to 'initiateShutdown'.
//
// Choosing 2), assuming that calling the (completion) callback from a
// thread other than the *CLIENT* dispatcher thread is ok. The
// 'mwcu::OperationChainLink' expects the completion callback from multiple
// sessions anyway.

bsl::shared_ptr<ClientSession> ptr = d_self.acquire();

if (!ptr) {
callback();
}
else {
dispatcher()->execute(
bdlf::BindUtil::bind(
bdlf::MemFnUtil::memFn(
&ClientSession::initiateShutdownDispatched,
d_self.acquire()),
callback,
timeout),
this,
mqbi::DispatcherEventType::e_DISPATCHER);
// Use 'mqbi::DispatcherEventType::e_DISPATCHER' to avoid (re)enabling
// 'd_flushList'
}
}

void ClientSession::invalidate()
Expand Down

0 comments on commit 8c9b078

Please sign in to comment.