| 478 | static list<CNode*> vNodesDisconnected; |
| 479 | |
| 480 | void ThreadSocketHandler() { |
| 481 | uint32_t nPrevNodeCount = 0; |
| 482 | while (true) { |
| 483 | // |
| 484 | // Disconnect nodes |
| 485 | // |
| 486 | { |
| 487 | LOCK(cs_vNodes); |
| 488 | // Disconnect unused nodes |
| 489 | vector<CNode*> vNodesCopy = vNodes; |
| 490 | for (auto pNode : vNodesCopy) { |
| 491 | if (pNode->fDisconnect || (pNode->GetRefCount() <= 0 && pNode->vRecvMsg.empty() && |
| 492 | pNode->nSendSize == 0 && pNode->ssSend.empty())) { |
| 493 | // remove from vNodes |
| 494 | vNodes.erase(remove(vNodes.begin(), vNodes.end(), pNode), vNodes.end()); |
| 495 | |
| 496 | // release outbound grant (if any) |
| 497 | pNode->grantOutbound.Release(); |
| 498 | |
| 499 | // close socket and cleanup |
| 500 | pNode->CloseSocketDisconnect(); |
| 501 | pNode->Cleanup(); |
| 502 | |
| 503 | // hold in disconnected pool until all refs are released |
| 504 | if (pNode->fNetworkNode || pNode->fInbound) |
| 505 | pNode->Release(); |
| 506 | vNodesDisconnected.push_back(pNode); |
| 507 | } |
| 508 | } |
| 509 | } |
| 510 | { |
| 511 | // Delete disconnected nodes |
| 512 | list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected; |
| 513 | for (auto pNode : vNodesDisconnectedCopy) { |
| 514 | // wait until threads are done using it |
| 515 | if (pNode->GetRefCount() <= 0) { |
| 516 | bool fDelete = false; |
| 517 | { |
| 518 | TRY_LOCK(pNode->cs_vSend, lockSend); |
| 519 | if (lockSend) { |
| 520 | TRY_LOCK(pNode->cs_vRecvMsg, lockRecv); |
| 521 | if (lockRecv) { |
| 522 | TRY_LOCK(pNode->cs_inventory, lockInv); |
| 523 | if (lockInv) |
| 524 | fDelete = true; |
| 525 | } |
| 526 | } |
| 527 | } |
| 528 | if (fDelete) { |
| 529 | vNodesDisconnected.remove(pNode); |
| 530 | delete pNode; |
| 531 | } |
| 532 | } |
| 533 | } |
| 534 | } |
| 535 | if (vNodes.size() != nPrevNodeCount) { |
| 536 | nPrevNodeCount = vNodes.size(); |
| 537 |
nothing calls this directly
no test coverage detected