@@ -35,7 +35,7 @@ void ThreadOpenAddedConnections2(void* parg);
35
35
void ThreadMapPort2 (void * parg);
36
36
#endif
37
37
void ThreadDNSAddressSeed2 (void * parg);
38
- bool OpenNetworkConnection (const CAddress& addrConnect, const char *strDest = NULL , bool fOneShot = false );
38
+ bool OpenNetworkConnection (const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL , const char *strDest = NULL , bool fOneShot = false );
39
39
40
40
41
41
@@ -66,10 +66,7 @@ CCriticalSection cs_vOneShots;
66
66
set<CNetAddr> setservAddNodeAddresses;
67
67
CCriticalSection cs_setservAddNodeAddresses;
68
68
69
- static CWaitableCriticalSection csOutbound;
70
- static int nOutbound = 0 ;
71
- static CConditionVariable condOutbound;
72
-
69
+ static CSemaphore *semOutbound = NULL ;
73
70
74
71
void AddOneShot (string strDest)
75
72
{
@@ -463,10 +460,6 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout)
463
460
LOCK (cs_vNodes);
464
461
vNodes.push_back (pnode);
465
462
}
466
- {
467
- WAITABLE_LOCK (csOutbound);
468
- nOutbound++;
469
- }
470
463
471
464
pnode->nTimeConnected = GetTime ();
472
465
return pnode;
@@ -612,14 +605,8 @@ void ThreadSocketHandler2(void* parg)
612
605
// remove from vNodes
613
606
vNodes.erase (remove (vNodes.begin (), vNodes.end (), pnode), vNodes.end ());
614
607
615
- if (!pnode->fInbound )
616
- {
617
- WAITABLE_LOCK (csOutbound);
618
- nOutbound--;
619
-
620
- // Connection slot(s) were removed, notify connection creator(s)
621
- NOTIFY (condOutbound);
622
- }
608
+ // release outbound grant (if any)
609
+ pnode->grantOutbound .Release ();
623
610
624
611
// close socket and cleanup
625
612
pnode->CloseSocketDisconnect ();
@@ -1295,8 +1282,11 @@ void static ProcessOneShot()
1295
1282
vOneShots.pop_front ();
1296
1283
}
1297
1284
CAddress addr;
1298
- if (!OpenNetworkConnection (addr, strDest.c_str (), true ))
1299
- AddOneShot (strDest);
1285
+ CSemaphoreGrant grant (*semOutbound, true );
1286
+ if (grant) {
1287
+ if (!OpenNetworkConnection (addr, &grant, strDest.c_str (), true ))
1288
+ AddOneShot (strDest);
1289
+ }
1300
1290
}
1301
1291
1302
1292
void ThreadOpenConnections2 (void * parg)
@@ -1312,7 +1302,7 @@ void ThreadOpenConnections2(void* parg)
1312
1302
BOOST_FOREACH (string strAddr, mapMultiArgs[" -connect" ])
1313
1303
{
1314
1304
CAddress addr;
1315
- OpenNetworkConnection (addr, strAddr.c_str ());
1305
+ OpenNetworkConnection (addr, NULL , strAddr.c_str ());
1316
1306
for (int i = 0 ; i < 10 && i < nLoop; i++)
1317
1307
{
1318
1308
Sleep (500 );
@@ -1335,13 +1325,9 @@ void ThreadOpenConnections2(void* parg)
1335
1325
if (fShutdown )
1336
1326
return ;
1337
1327
1338
- // Limit outbound connections
1339
- int nMaxOutbound = min (MAX_OUTBOUND_CONNECTIONS, (int )GetArg (" -maxconnections" , 125 ));
1328
+
1340
1329
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1341
- {
1342
- WAITABLE_LOCK (csOutbound);
1343
- WAIT (condOutbound, fShutdown || nOutbound < nMaxOutbound);
1344
- }
1330
+ CSemaphoreGrant grant (*semOutbound);
1345
1331
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1346
1332
if (fShutdown )
1347
1333
return ;
@@ -1374,11 +1360,15 @@ void ThreadOpenConnections2(void* parg)
1374
1360
1375
1361
// Only connect to one address per a.b.?.? range.
1376
1362
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1363
+ int nOutbound = 0 ;
1377
1364
set<vector<unsigned char > > setConnected;
1378
1365
{
1379
1366
LOCK (cs_vNodes);
1380
- BOOST_FOREACH (CNode* pnode, vNodes)
1367
+ BOOST_FOREACH (CNode* pnode, vNodes) {
1381
1368
setConnected.insert (pnode->addr .GetGroup ());
1369
+ if (!pnode->fInbound )
1370
+ nOutbound++;
1371
+ }
1382
1372
}
1383
1373
1384
1374
int64 nANow = GetAdjustedTime ();
@@ -1408,7 +1398,7 @@ void ThreadOpenConnections2(void* parg)
1408
1398
}
1409
1399
1410
1400
if (addrConnect.IsValid ())
1411
- OpenNetworkConnection (addrConnect);
1401
+ OpenNetworkConnection (addrConnect, &grant );
1412
1402
}
1413
1403
}
1414
1404
@@ -1442,7 +1432,8 @@ void ThreadOpenAddedConnections2(void* parg)
1442
1432
while (!fShutdown ) {
1443
1433
BOOST_FOREACH (string& strAddNode, mapMultiArgs[" -addnode" ]) {
1444
1434
CAddress addr;
1445
- OpenNetworkConnection (addr, strAddNode.c_str ());
1435
+ CSemaphoreGrant grant (*semOutbound);
1436
+ OpenNetworkConnection (addr, &grant, strAddNode.c_str ());
1446
1437
Sleep (500 );
1447
1438
}
1448
1439
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
@@ -1485,7 +1476,8 @@ void ThreadOpenAddedConnections2(void* parg)
1485
1476
}
1486
1477
BOOST_FOREACH (vector<CService>& vserv, vservConnectAddresses)
1487
1478
{
1488
- OpenNetworkConnection (CAddress (*(vserv.begin ())));
1479
+ CSemaphoreGrant grant (*semOutbound);
1480
+ OpenNetworkConnection (CAddress (*(vserv.begin ())), &grant);
1489
1481
Sleep (500 );
1490
1482
if (fShutdown )
1491
1483
return ;
@@ -1500,7 +1492,8 @@ void ThreadOpenAddedConnections2(void* parg)
1500
1492
}
1501
1493
}
1502
1494
1503
- bool OpenNetworkConnection (const CAddress& addrConnect, const char *strDest, bool fOneShot )
1495
+ // if succesful, this moves the passed grant to the constructed node
1496
+ bool OpenNetworkConnection (const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot )
1504
1497
{
1505
1498
//
1506
1499
// Initiate outbound network connection
@@ -1522,6 +1515,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, const char *strDest, boo
1522
1515
return false ;
1523
1516
if (!pnode)
1524
1517
return false ;
1518
+ if (grantOutbound)
1519
+ grantOutbound->MoveTo (pnode->grantOutbound );
1525
1520
pnode->fNetworkNode = true ;
1526
1521
if (fOneShot )
1527
1522
pnode->fOneShot = true ;
@@ -1770,6 +1765,12 @@ void StartNode(void* parg)
1770
1765
#endif
1771
1766
#endif
1772
1767
1768
+ if (semOutbound == NULL ) {
1769
+ // initialize semaphore
1770
+ int nMaxOutbound = min (MAX_OUTBOUND_CONNECTIONS, (int )GetArg (" -maxconnections" , 125 ));
1771
+ semOutbound = new CSemaphore (nMaxOutbound);
1772
+ }
1773
+
1773
1774
if (pnodeLocalHost == NULL )
1774
1775
pnodeLocalHost = new CNode (INVALID_SOCKET, CAddress (CService (" 127.0.0.1" , 0 ), nLocalServices));
1775
1776
@@ -1823,7 +1824,8 @@ bool StopNode()
1823
1824
fShutdown = true ;
1824
1825
nTransactionsUpdated++;
1825
1826
int64 nStart = GetTime ();
1826
- NOTIFY_ALL (condOutbound);
1827
+ for (int i=0 ; i<MAX_OUTBOUND_CONNECTIONS; i++)
1828
+ semOutbound->post ();
1827
1829
do
1828
1830
{
1829
1831
int nThreadsRunning = 0 ;
0 commit comments