Skip to content

Commit fb2004a

Browse files
Fix[bmqio]: return peerUri by value to eliminate data race (#1641)
Return `peerUri` by value instead of by const reference so the caller is not left holding an unprotected reference after the lock drops. This changes the base `Channel` interface and all four implementations. In `ResolvingChannelFactory_Channel`, the constructor previously took the address of the return value for the `AtomicPointer` pattern, so a stored copy is used instead. Also fixes two latent `StringRef` dangles that only worked because `peerUri` returned a reference to a stable member. Signed-off-by: Srinath Satuluri <satulurisrinath@gmail.com>
1 parent fa52349 commit fb2004a

15 files changed

Lines changed: 34 additions & 30 deletions

src/groups/bmq/bmqio/bmqio_channel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class Channel {
219219

220220
/// Return the URI of the "remote" end of this channel. It is up to the
221221
/// underlying implementation to define the format of the returned URI.
222-
virtual const bsl::string& peerUri() const = 0;
222+
virtual bsl::string peerUri() const = 0;
223223

224224
/// Return a reference providing modifiable access to the properties of
225225
/// this Channel.

src/groups/bmq/bmqio/bmqio_decoratingchannelpartialimp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class DecoratingChannelPartialImp : public Channel {
100100
Channel* base() const;
101101

102102
// Channel
103-
const bsl::string& peerUri() const BSLS_KEYWORD_OVERRIDE;
103+
bsl::string peerUri() const BSLS_KEYWORD_OVERRIDE;
104104

105105
/// Forward to the underlying base `Channel`.
106106
const bmqvt::PropertyBag& properties() const BSLS_KEYWORD_OVERRIDE;
@@ -177,7 +177,7 @@ inline Channel* DecoratingChannelPartialImp::base() const
177177
return d_base.get();
178178
}
179179

180-
inline const bsl::string& DecoratingChannelPartialImp::peerUri() const
180+
inline bsl::string DecoratingChannelPartialImp::peerUri() const
181181
{
182182
return d_base->peerUri();
183183
}

src/groups/bmq/bmqio/bmqio_ntcchannel.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,8 +1342,9 @@ ntsa::Endpoint NtcChannel::sourceEndpoint() const
13421342
: ntsa::Endpoint();
13431343
}
13441344

1345-
const bsl::string& NtcChannel::peerUri() const
1345+
bsl::string NtcChannel::peerUri() const
13461346
{
1347+
bslmt::LockGuard<bslmt::Mutex> lock(&d_mutex);
13471348
return d_peerUri;
13481349
}
13491350

src/groups/bmq/bmqio/bmqio_ntcchannel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ class NtcChannel : public bmqio::Channel,
423423

424424
/// Return the URI of the "remote" end of this channel. It is up to the
425425
/// underlying implementation to define the format of the returned URI.
426-
const bsl::string& peerUri() const BSLS_KEYWORD_OVERRIDE;
426+
bsl::string peerUri() const BSLS_KEYWORD_OVERRIDE;
427427

428428
/// Return a reference providing modifiable access to the properties of
429429
/// this Channel.

src/groups/bmq/bmqio/bmqio_ntcchannel.t.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void executeOnClosedChannelFunc(bmqio::NtcChannel* channel,
8888
BSLA_MAYBE_UNUSED ntsa::Endpoint peerEndpoint = channel->peerEndpoint();
8989
BSLA_MAYBE_UNUSED ntsa::Endpoint sourceEndpoint =
9090
channel->sourceEndpoint();
91-
BSLA_MAYBE_UNUSED const bsl::string& peerUri = channel->peerUri();
91+
BSLA_MAYBE_UNUSED bsl::string peerUri = channel->peerUri();
9292
BSLA_MAYBE_UNUSED bmqvt::PropertyBag& properties = channel->properties();
9393

9494
channel->setChannelId(id);

src/groups/bmq/bmqio/bmqio_ntcchannelfactory.t.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ void Tester::checkChannelUri(int line,
10511051
return; // RETURN
10521052
}
10531053

1054-
bslstl::StringRef uri = info.d_channel->peerUri();
1054+
bsl::string uri = info.d_channel->peerUri();
10551055
BMQTST_ASSERT_EQ_D(line,
10561056
uri.data(),
10571057
bdlb::StringRefUtil::strstr(uri, prefix).data());

src/groups/bmq/bmqio/bmqio_resolvingchannelfactory.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ ResolvingChannelFactory_Channel::ResolvingChannelFactory_Channel(
9595
bslma::Allocator* basicAllocator)
9696
: DecoratingChannelPartialImp(channel, basicAllocator)
9797
, d_resolvedPeerUri(basicAllocator)
98+
, d_basePeerUri(channel->peerUri(), basicAllocator)
9899
, d_peerUri()
99100
{
100101
// PRECONDITIONS
101102
BSLS_ASSERT(channel);
102103

103-
d_peerUri = &channel->peerUri();
104+
d_peerUri = &d_basePeerUri;
104105
}
105106

106107
// MANIPULATORS
@@ -117,7 +118,7 @@ void ResolvingChannelFactory_Channel::updatePeerUri()
117118
}
118119

119120
// ACCESSORS
120-
const bsl::string& ResolvingChannelFactory_Channel::peerUri() const
121+
bsl::string ResolvingChannelFactory_Channel::peerUri() const
121122
{
122123
return *d_peerUri;
123124
}
@@ -235,7 +236,7 @@ void ResolvingChannelFactoryUtil::defaultResolutionFn(
235236
const ResolveFn& resolveFn,
236237
bool verbose)
237238
{
238-
bslstl::StringRef peerUri = baseChannel.peerUri();
239+
bsl::string peerUri = baseChannel.peerUri();
239240
bslstl::StringRef colon = bdlb::StringRefUtil::strstr(peerUri, ":");
240241
if (colon.length() == 0) {
241242
if (verbose) {
@@ -248,7 +249,7 @@ void ResolvingChannelFactoryUtil::defaultResolutionFn(
248249

249250
bdlma::LocalSequentialAllocator<128> arena;
250251

251-
bsl::string ipAddrStr(peerUri.data(), colon.data(), &arena);
252+
bsl::string ipAddrStr(peerUri.c_str(), colon.data(), &arena);
252253
ntsa::IpAddress ipAddr;
253254

254255
if (!ipAddr.parse(ipAddrStr)) {
@@ -277,7 +278,7 @@ void ResolvingChannelFactoryUtil::defaultResolutionFn(
277278
resolvedUri->append(ipAddrStr);
278279
resolvedUri->append(1, '~');
279280
resolvedUri->append(resolvedName);
280-
resolvedUri->append(colon.data(), peerUri.end());
281+
resolvedUri->append(colon.data(), peerUri.c_str() + peerUri.length());
281282
}
282283

283284
} // close package namespace

src/groups/bmq/bmqio/bmqio_resolvingchannelfactory.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class ResolvingChannelFactory_Channel : public DecoratingChannelPartialImp {
140140
// PRIVATE DATA
141141
bsl::string d_resolvedPeerUri;
142142

143+
bsl::string d_basePeerUri;
144+
143145
bsls::AtomicPointer<const bsl::string> d_peerUri;
144146

145147
private:
@@ -177,7 +179,7 @@ class ResolvingChannelFactory_Channel : public DecoratingChannelPartialImp {
177179

178180
/// Return our base Channel's peerUri until our resolution is done, and
179181
/// start returning the resolved peerUri after that.
180-
const bsl::string& peerUri() const BSLS_KEYWORD_OVERRIDE;
182+
bsl::string peerUri() const BSLS_KEYWORD_OVERRIDE;
181183
};
182184

183185
// =============================

src/groups/bmq/bmqio/bmqio_testchannel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ bmqvt::PropertyBag& TestChannel::properties()
163163
return d_properties;
164164
}
165165

166-
const bsl::string& TestChannel::peerUri() const
166+
bsl::string TestChannel::peerUri() const
167167
{
168168
return d_peerUri;
169169
}

src/groups/bmq/bmqio/bmqio_testchannel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class TestChannel : public Channel {
308308

309309
// ACCESSORS
310310
// Channel
311-
const bsl::string& peerUri() const BSLS_KEYWORD_OVERRIDE;
311+
bsl::string peerUri() const BSLS_KEYWORD_OVERRIDE;
312312
const bmqvt::PropertyBag& properties() const BSLS_KEYWORD_OVERRIDE;
313313
};
314314

0 commit comments

Comments
 (0)