Skip to content

Commit 4d265d0

Browse files
committed
sync: modernize CSemaphore / CSemaphoreGrant
1 parent c73cd42 commit 4d265d0

File tree

4 files changed

+65
-35
lines changed

4 files changed

+65
-35
lines changed

src/net.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,7 +1862,7 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
18621862
CSemaphoreGrant grant(*semOutbound, true);
18631863
if (!grant) return false;
18641864

1865-
OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type, /*use_v2transport=*/false);
1865+
OpenNetworkConnection(CAddress(), false, std::move(grant), address.c_str(), conn_type, /*use_v2transport=*/false);
18661866
return true;
18671867
}
18681868

@@ -2294,9 +2294,9 @@ void CConnman::ProcessAddrFetch()
22942294
m_addr_fetches.pop_front();
22952295
}
22962296
CAddress addr;
2297-
CSemaphoreGrant grant(*semOutbound, true);
2297+
CSemaphoreGrant grant(*semOutbound, /*fTry=*/true);
22982298
if (grant) {
2299-
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH, /*use_v2transport=*/false);
2299+
OpenNetworkConnection(addr, false, std::move(grant), strDest.c_str(), ConnectionType::ADDR_FETCH, /*use_v2transport=*/false);
23002300
}
23012301
}
23022302

@@ -2398,7 +2398,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
23982398
for (const std::string& strAddr : connect)
23992399
{
24002400
CAddress addr(CService(), NODE_NONE);
2401-
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
2401+
OpenNetworkConnection(addr, false, {}, strAddr.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
24022402
for (int i = 0; i < 10 && i < nLoop; i++)
24032403
{
24042404
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
@@ -2703,7 +2703,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
27032703
const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(nMaxConnections - 1, 2)};
27042704
// Use BIP324 transport when both us and them have NODE_V2_P2P set.
27052705
const bool use_v2transport(addrConnect.nServices & GetLocalServices() & NODE_P2P_V2);
2706-
OpenNetworkConnection(addrConnect, count_failures, &grant, /*strDest=*/nullptr, conn_type, use_v2transport);
2706+
OpenNetworkConnection(addrConnect, count_failures, std::move(grant), /*strDest=*/nullptr, conn_type, use_v2transport);
27072707
}
27082708
}
27092709
}
@@ -2785,16 +2785,16 @@ void CConnman::ThreadOpenAddedConnections()
27852785
bool tried = false;
27862786
for (const AddedNodeInfo& info : vInfo) {
27872787
if (!info.fConnected) {
2788-
if (!grant.TryAcquire()) {
2788+
if (!grant) {
27892789
// If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
27902790
// the addednodeinfo state might change.
27912791
break;
27922792
}
27932793
tried = true;
27942794
CAddress addr(CService(), NODE_NONE);
2795-
OpenNetworkConnection(addr, false, &grant, info.m_params.m_added_node.c_str(), ConnectionType::MANUAL, info.m_params.m_use_v2transport);
2796-
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
2797-
return;
2795+
OpenNetworkConnection(addr, false, std::move(grant), info.m_params.m_added_node.c_str(), ConnectionType::MANUAL, info.m_params.m_use_v2transport);
2796+
if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) return;
2797+
grant = CSemaphoreGrant(*semAddnode, /*fTry=*/true);
27982798
}
27992799
}
28002800
// Retry every 60 seconds if a connection was attempted, otherwise two seconds
@@ -2804,7 +2804,7 @@ void CConnman::ThreadOpenAddedConnections()
28042804
}
28052805

28062806
// if successful, this moves the passed grant to the constructed node
2807-
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type, bool use_v2transport)
2807+
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant&& grant_outbound, const char *pszDest, ConnectionType conn_type, bool use_v2transport)
28082808
{
28092809
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
28102810
assert(conn_type != ConnectionType::INBOUND);
@@ -2830,8 +2830,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
28302830

28312831
if (!pnode)
28322832
return;
2833-
if (grantOutbound)
2834-
grantOutbound->MoveTo(pnode->grantOutbound);
2833+
pnode->grantOutbound = std::move(grant_outbound);
28352834

28362835
m_msgproc->InitializeNode(*pnode, nLocalServices);
28372836
{

src/net.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ class CConnman
11071107
bool GetNetworkActive() const { return fNetworkActive; };
11081108
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
11091109
void SetNetworkActive(bool active);
1110-
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound, const char* strDest, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
1110+
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant&& grant_outbound, const char* strDest, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
11111111
bool CheckIncomingNonce(uint64_t nonce);
11121112

11131113
// alias for thread safety annotations only, not defined

src/rpc/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ static RPCHelpMan addnode()
317317
if (command == "onetry")
318318
{
319319
CAddress addr;
320-
connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grantOutbound=*/nullptr, node_arg.c_str(), ConnectionType::MANUAL, use_v2transport);
320+
connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grant_outbound=*/{}, node_arg.c_str(), ConnectionType::MANUAL, use_v2transport);
321321
return UniValue::VNULL;
322322
}
323323

src/sync.h

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ inline MutexType* MaybeCheckNotHeld(MutexType* m) LOCKS_EXCLUDED(m) LOCK_RETURNE
301301
//! gcc and the -Wreturn-stack-address flag in clang, both enabled by default.
302302
#define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())
303303

304+
/** An implementation of a semaphore.
305+
*
306+
* See https://en.wikipedia.org/wiki/Semaphore_(programming)
307+
*/
304308
class CSemaphore
305309
{
306310
private:
@@ -309,25 +313,33 @@ class CSemaphore
309313
int value;
310314

311315
public:
312-
explicit CSemaphore(int init) : value(init) {}
316+
explicit CSemaphore(int init) noexcept : value(init) {}
313317

314-
void wait()
318+
// Disallow default construct, copy, move.
319+
CSemaphore() = delete;
320+
CSemaphore(const CSemaphore&) = delete;
321+
CSemaphore(CSemaphore&&) = delete;
322+
CSemaphore& operator=(const CSemaphore&) = delete;
323+
CSemaphore& operator=(CSemaphore&&) = delete;
324+
325+
void wait() noexcept
315326
{
316327
std::unique_lock<std::mutex> lock(mutex);
317328
condition.wait(lock, [&]() { return value >= 1; });
318329
value--;
319330
}
320331

321-
bool try_wait()
332+
bool try_wait() noexcept
322333
{
323334
std::lock_guard<std::mutex> lock(mutex);
324-
if (value < 1)
335+
if (value < 1) {
325336
return false;
337+
}
326338
value--;
327339
return true;
328340
}
329341

330-
void post()
342+
void post() noexcept
331343
{
332344
{
333345
std::lock_guard<std::mutex> lock(mutex);
@@ -345,53 +357,72 @@ class CSemaphoreGrant
345357
bool fHaveGrant;
346358

347359
public:
348-
void Acquire()
360+
void Acquire() noexcept
349361
{
350-
if (fHaveGrant)
362+
if (fHaveGrant) {
351363
return;
364+
}
352365
sem->wait();
353366
fHaveGrant = true;
354367
}
355368

356-
void Release()
369+
void Release() noexcept
357370
{
358-
if (!fHaveGrant)
371+
if (!fHaveGrant) {
359372
return;
373+
}
360374
sem->post();
361375
fHaveGrant = false;
362376
}
363377

364-
bool TryAcquire()
378+
bool TryAcquire() noexcept
365379
{
366-
if (!fHaveGrant && sem->try_wait())
380+
if (!fHaveGrant && sem->try_wait()) {
367381
fHaveGrant = true;
382+
}
368383
return fHaveGrant;
369384
}
370385

371-
void MoveTo(CSemaphoreGrant& grant)
386+
// Disallow copy.
387+
CSemaphoreGrant(const CSemaphoreGrant&) = delete;
388+
CSemaphoreGrant& operator=(const CSemaphoreGrant&) = delete;
389+
390+
// Allow move.
391+
CSemaphoreGrant(CSemaphoreGrant&& other) noexcept
392+
{
393+
sem = other.sem;
394+
fHaveGrant = other.fHaveGrant;
395+
other.fHaveGrant = false;
396+
other.sem = nullptr;
397+
}
398+
399+
CSemaphoreGrant& operator=(CSemaphoreGrant&& other) noexcept
372400
{
373-
grant.Release();
374-
grant.sem = sem;
375-
grant.fHaveGrant = fHaveGrant;
376-
fHaveGrant = false;
401+
Release();
402+
sem = other.sem;
403+
fHaveGrant = other.fHaveGrant;
404+
other.fHaveGrant = false;
405+
other.sem = nullptr;
406+
return *this;
377407
}
378408

379-
CSemaphoreGrant() : sem(nullptr), fHaveGrant(false) {}
409+
CSemaphoreGrant() noexcept : sem(nullptr), fHaveGrant(false) {}
380410

381-
explicit CSemaphoreGrant(CSemaphore& sema, bool fTry = false) : sem(&sema), fHaveGrant(false)
411+
explicit CSemaphoreGrant(CSemaphore& sema, bool fTry = false) noexcept : sem(&sema), fHaveGrant(false)
382412
{
383-
if (fTry)
413+
if (fTry) {
384414
TryAcquire();
385-
else
415+
} else {
386416
Acquire();
417+
}
387418
}
388419

389420
~CSemaphoreGrant()
390421
{
391422
Release();
392423
}
393424

394-
operator bool() const
425+
explicit operator bool() const noexcept
395426
{
396427
return fHaveGrant;
397428
}

0 commit comments

Comments
 (0)