Condition variable for outbound connection slots

Keep a global counter for nOutbound, protected with its own waitable
critical section, and wait when all outbound slots are filled, rather
than polling.

This removes the (on average) 1 second delay between a lost connection
and a new connection attempt, and may speed up shutdowns.
This commit is contained in:
Pieter Wuille 2012-04-04 16:01:57 +02:00
parent 712fd182b7
commit 092631f0ba
1 changed files with 22 additions and 19 deletions

View File

@ -64,6 +64,9 @@ map<CInv, int64> mapAlreadyAskedFor;
set<CNetAddr> setservAddNodeAddresses; set<CNetAddr> setservAddNodeAddresses;
CCriticalSection cs_setservAddNodeAddresses; CCriticalSection cs_setservAddNodeAddresses;
static CWaitableCriticalSection csOutbound;
static int nOutbound = 0;
static CConditionVariable condOutbound;
unsigned short GetListenPort() unsigned short GetListenPort()
@ -460,6 +463,8 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
pnode->AddRef(); pnode->AddRef();
CRITICAL_BLOCK(cs_vNodes) CRITICAL_BLOCK(cs_vNodes)
vNodes.push_back(pnode); vNodes.push_back(pnode);
WAITABLE_CRITICAL_BLOCK(csOutbound)
nOutbound++;
pnode->nTimeConnected = GetTime(); pnode->nTimeConnected = GetTime();
return pnode; return pnode;
@ -610,6 +615,15 @@ void ThreadSocketHandler2(void* parg)
// remove from vNodes // remove from vNodes
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
if (!pnode->fInbound)
WAITABLE_CRITICAL_BLOCK(csOutbound)
{
nOutbound--;
// Connection slot(s) were removed, notify connection creator(s)
NOTIFY(condOutbound);
}
// close socket and cleanup // close socket and cleanup
pnode->CloseSocketDisconnect(); pnode->CloseSocketDisconnect();
pnode->Cleanup(); pnode->Cleanup();
@ -1278,8 +1292,6 @@ void ThreadOpenConnections2(void* parg)
int64 nStart = GetTime(); int64 nStart = GetTime();
loop loop
{ {
int nOutbound = 0;
vnThreadsRunning[THREAD_OPENCONNECTIONS]--; vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
Sleep(500); Sleep(500);
vnThreadsRunning[THREAD_OPENCONNECTIONS]++; vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
@ -1287,23 +1299,13 @@ void ThreadOpenConnections2(void* parg)
return; return;
// Limit outbound connections // Limit outbound connections
loop int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
{ vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
nOutbound = 0; WAITABLE_CRITICAL_BLOCK(csOutbound)
CRITICAL_BLOCK(cs_vNodes) WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
BOOST_FOREACH(CNode* pnode, vNodes) vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (!pnode->fInbound) if (fShutdown)
nOutbound++; return;
int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
if (nOutbound < nMaxOutboundConnections)
break;
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
Sleep(2000);
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return;
}
bool fAddSeeds = false; bool fAddSeeds = false;
@ -1752,6 +1754,7 @@ bool StopNode()
fShutdown = true; fShutdown = true;
nTransactionsUpdated++; nTransactionsUpdated++;
int64 nStart = GetTime(); int64 nStart = GetTime();
NOTIFY_ALL(condOutbound);
do do
{ {
int nThreadsRunning = 0; int nThreadsRunning = 0;