diff options
author | Jonas Schnelli <jonas.schnelli@include7.ch> | 2013-06-03 15:18:41 +0200 |
---|---|---|
committer | Jonas Schnelli <jonas.schnelli@include7.ch> | 2013-06-03 15:18:41 +0200 |
commit | 39fe9de6b2b255969971beca8fa25a33ad2e5750 (patch) | |
tree | 6686041f6b801d0ea5185b026a480a5be61510e6 /src/net.cpp | |
parent | f679b2900a3a9f863f888cfb0b1a5e593628e37b (diff) | |
parent | fa9e5adddda0bee5adc040b957cf3f1a6a470802 (diff) |
Merge branch 'master' of git://github.com/bitcoin/bitcoin into prefsFix
Signed-off-by: Jonas Schnelli <jonas.schnelli@include7.ch>
Conflicts:
bitcoin-qt.pro
Diffstat (limited to 'src/net.cpp')
-rw-r--r-- | src/net.cpp | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/net.cpp b/src/net.cpp index 3fa48ae484..54ed1d9b51 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -841,19 +841,39 @@ void ThreadSocketHandler() { if (pnode->hSocket == INVALID_SOCKET) continue; + FD_SET(pnode->hSocket, &fdsetError); + hSocketMax = max(hSocketMax, pnode->hSocket); + have_fds = true; + + // Implement the following logic: + // * If there is data to send, select() for sending data. As this only + // happens when optimistic write failed, we choose to first drain the + // write buffer in this case before receiving more. This avoids + // needlessly queueing received data, if the remote peer is not themselves + // receiving data. This means properly utilizing TCP flow control signalling. + // * Otherwise, if there is no (complete) message in the receive buffer, + // or there is space left in the buffer, select() for receiving data. + // * (if neither of the above applies, there is certainly one message + // in the receiver buffer ready to be processed). + // Together, that means that at least one of the following is always possible, + // so we don't deadlock: + // * We send some data. + // * We wait for data to be received (and disconnect after timeout). + // * We process a message in the buffer (message handler thread). { TRY_LOCK(pnode->cs_vSend, lockSend); - if (lockSend) { - // do not read, if draining write queue - if (!pnode->vSendMsg.empty()) - FD_SET(pnode->hSocket, &fdsetSend); - else - FD_SET(pnode->hSocket, &fdsetRecv); - FD_SET(pnode->hSocket, &fdsetError); - hSocketMax = max(hSocketMax, pnode->hSocket); - have_fds = true; + if (lockSend && !pnode->vSendMsg.empty()) { + FD_SET(pnode->hSocket, &fdsetSend); + continue; } } + { + TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); + if (lockRecv && ( + pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() || + pnode->GetTotalRecvSize() <= ReceiveFloodSize())) + FD_SET(pnode->hSocket, &fdsetRecv); + } } } @@ -959,12 +979,7 @@ void ThreadSocketHandler() TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); if (lockRecv) { - if (pnode->GetTotalRecvSize() > ReceiveFloodSize()) { - if (!pnode->fDisconnect) - printf("socket recv flood control disconnect (%u bytes)\n", pnode->GetTotalRecvSize()); - pnode->CloseSocketDisconnect(); - } - else { + { // typical socket buffer is 8K-64K char pchBuf[0x10000]; int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); |