diff options
Diffstat (limited to 'src/net.cpp')
| -rw-r--r-- | src/net.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/net.cpp b/src/net.cpp index 3af0189..7091981 100644 --- a/src/net.cpp +++ b/src/net.cpp | |||
| @@ -1030,7 +1030,12 @@ void CNode::Disconnect() | |||
| 1030 | { | 1030 | { |
| 1031 | LogPrint("net", "disconnecting node %s\n", addr.ToString().c_str()); | 1031 | LogPrint("net", "disconnecting node %s\n", addr.ToString().c_str()); |
| 1032 | 1032 | ||
| 1033 | // Invalidate before anything else can look at it. This used to close the | ||
| 1034 | // socket and leave the handle number sitting in the object, so ~CNode | ||
| 1035 | // closed it a second time and the select loop kept arming it in the | ||
| 1036 | // meantime. See the note on ~CNode in net.h. | ||
| 1033 | BtfCloseSocket(hSocket); | 1037 | BtfCloseSocket(hSocket); |
| 1038 | hSocket = INVALID_SOCKET; | ||
| 1034 | 1039 | ||
| 1035 | // All of a nodes broadcasts and subscriptions are automatically torn down | 1040 | // All of a nodes broadcasts and subscriptions are automatically torn down |
| 1036 | // when it goes down, so a node has to stay up to keep its broadcast going. | 1041 | // when it goes down, so a node has to stay up to keep its broadcast going. |
| @@ -1210,6 +1215,11 @@ void ThreadSocketHandler2(void* parg) | |||
| 1210 | { | 1215 | { |
| 1211 | if (nWatched >= FD_SETSIZE) | 1216 | if (nWatched >= FD_SETSIZE) |
| 1212 | break; | 1217 | break; |
| 1218 | // A disconnected node stays in vNodes until its references go. | ||
| 1219 | // Arming its closed handle asks select() to watch a number the | ||
| 1220 | // operating system may already have given to somebody else. | ||
| 1221 | if (pnode->hSocket == INVALID_SOCKET) | ||
| 1222 | continue; | ||
| 1213 | FD_SET(pnode->hSocket, &fdsetRecv); | 1223 | FD_SET(pnode->hSocket, &fdsetRecv); |
| 1214 | nWatched++; | 1224 | nWatched++; |
| 1215 | hSocketMax = max(hSocketMax, pnode->hSocket); | 1225 | hSocketMax = max(hSocketMax, pnode->hSocket); |
| @@ -1272,6 +1282,11 @@ void ThreadSocketHandler2(void* parg) | |||
| 1272 | { | 1282 | { |
| 1273 | foreach(CNode* pnode, vNodes) | 1283 | foreach(CNode* pnode, vNodes) |
| 1274 | { | 1284 | { |
| 1285 | // Already disconnected: its handle is gone on purpose, and | ||
| 1286 | // reporting it here would name the wrong node for a select() | ||
| 1287 | // failure it did not cause. | ||
| 1288 | if (pnode->hSocket == INVALID_SOCKET) | ||
| 1289 | continue; | ||
| 1275 | int nType = 0; | 1290 | int nType = 0; |
| 1276 | #ifdef _WIN32 | 1291 | #ifdef _WIN32 |
| 1277 | int nTypeLen = sizeof(nType); | 1292 | int nTypeLen = sizeof(nType); |