changeset 23700:35573c2205d7

ptschip discovered CPU spin loop, fixed here
author Andrew Stone <g.andrew.stone@gmail.com>
date Tue, 23 Feb 2016 20:41:50 -0500
parents 7969db348bf5
children b934c46fd3a5
files src/net.cpp src/net.h
diffstat 2 files changed, 8 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/net.cpp	Tue Feb 23 20:16:25 2016 -0500
+++ b/src/net.cpp	Tue Feb 23 20:41:50 2016 -0500
@@ -744,9 +744,10 @@
 }
 
 
-// requires LOCK(cs_vSend)
-void SocketSendData(CNode* pnode)
+// requires LOCK(cs_vSend), BU: returns > 0 if any data was sent, 0 if nothing accomplished.
+int SocketSendData(CNode* pnode)
 {
+    int progress=0; // BU This variable is incremented if something happens.  If it is zero at the bottom of the loop, we delay.  This solves spin loop issues where the select does not block but no bytes can be transferred (traffic shaping limited, for example).
     std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
 
     while (it != pnode->vSendMsg.end()) {
@@ -758,6 +759,7 @@
             break;
         int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], amt2Send, MSG_NOSIGNAL | MSG_DONTWAIT);
         if (nBytes > 0) {
+            progress++;  // BU
             pnode->nLastSend = GetTime();
             pnode->nSendBytes += nBytes;
             pnode->nSendOffset += nBytes;
@@ -792,6 +794,7 @@
         assert(pnode->nSendSize == 0);
     }
     pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
+    return progress;
 }
 
 static list<CNode*> vNodesDisconnected;
@@ -1239,8 +1242,7 @@
             if (FD_ISSET(pnode->hSocket, &fdsetSend)) {
                 TRY_LOCK(pnode->cs_vSend, lockSend);
                 if (lockSend && sendShaper.try_leak(0)) {
-                    progress++;
-                    SocketSendData(pnode);
+                    progress += SocketSendData(pnode);
                 }
             }
 
@@ -1270,7 +1272,7 @@
                 pnode->Release();
         }
 
-        if (progress == 0) // Nothing happened even though select did not block.  So slow us down.
+        if (progress == 0) // BU: Nothing happened even though select did not block.  So slow us down.
             MilliSleep(50);
     }
 }
--- a/src/net.h	Tue Feb 23 20:16:25 2016 -0500
+++ b/src/net.h	Tue Feb 23 20:41:50 2016 -0500
@@ -95,7 +95,7 @@
 bool BindListenPort(const CService& bindAddr, std::string& strError, bool fWhitelisted = false);
 void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler);
 bool StopNode();
-void SocketSendData(CNode* pnode);
+int SocketSendData(CNode* pnode);
 
 typedef int NodeId;