| 932 | } |
| 933 | |
| 934 | void ThreadSocketHandler() |
| 935 | { |
| 936 | unsigned int nPrevNodeCount = 0; |
| 937 | while (true) { |
| 938 | // |
| 939 | // Disconnect nodes |
| 940 | // |
| 941 | { |
| 942 | vector<CNode*> vNodesCopy; |
| 943 | { |
| 944 | LOCK(cs_vNodes); |
| 945 | vNodesCopy = vNodes; |
| 946 | } |
| 947 | |
| 948 | // Disconnect unused nodes |
| 949 | for (CNode* pnode : vNodesCopy) { |
| 950 | if (pnode && (pnode->fDisconnect || |
| 951 | (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))) { |
| 952 | |
| 953 | // Lock the node to avoid race |
| 954 | LOCK(cs_vNodes); |
| 955 | |
| 956 | // remove from vNodes |
| 957 | vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); |
| 958 | |
| 959 | // release outbound grant (if any) |
| 960 | pnode->grantOutbound.Release(); |
| 961 | |
| 962 | // close socket and cleanup |
| 963 | pnode->CloseSocketDisconnect(); |
| 964 | |
| 965 | // hold in disconnected pool until all refs are released |
| 966 | if (pnode->fNetworkNode || pnode->fInbound) |
| 967 | pnode->Release(); |
| 968 | vNodesDisconnected.push_back(pnode); |
| 969 | } |
| 970 | } |
| 971 | } |
| 972 | { |
| 973 | // Delete disconnected nodes |
| 974 | list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected; |
| 975 | for (CNode* pnode : vNodesDisconnectedCopy) { |
| 976 | // wait until threads are done using it |
| 977 | if (pnode && pnode->GetRefCount() <= 0) { |
| 978 | bool fDelete = false; |
| 979 | { |
| 980 | TRY_LOCK(pnode->cs_vSend, lockSend); |
| 981 | if (lockSend) { |
| 982 | TRY_LOCK(pnode->cs_vRecvMsg, lockRecv); |
| 983 | if (lockRecv) { |
| 984 | TRY_LOCK(pnode->cs_inventory, lockInv); |
| 985 | if (lockInv) |
| 986 | fDelete = true; |
| 987 | } |
| 988 | } |
| 989 | } |
| 990 | if (fDelete) { |
| 991 | vNodesDisconnected.remove(pnode); |
nothing calls this directly
no test coverage detected