@@ -425,6 +425,7 @@ void CConnman::DumpBanlist()
425
425
void CNode::CloseSocketDisconnect ()
426
426
{
427
427
fDisconnect = true ;
428
+ LOCK (cs_hSocket);
428
429
if (hSocket != INVALID_SOCKET)
429
430
{
430
431
LogPrint (" net" , " disconnecting peer=%d\n " , id);
@@ -789,7 +790,13 @@ size_t CConnman::SocketSendData(CNode *pnode) const
789
790
while (it != pnode->vSendMsg .end ()) {
790
791
const auto &data = *it;
791
792
assert (data.size () > pnode->nSendOffset );
792
- int nBytes = send (pnode->hSocket , reinterpret_cast <const char *>(data.data ()) + pnode->nSendOffset , data.size () - pnode->nSendOffset , MSG_NOSIGNAL | MSG_DONTWAIT);
793
+ int nBytes = 0 ;
794
+ {
795
+ LOCK (pnode->cs_hSocket );
796
+ if (pnode->hSocket == INVALID_SOCKET)
797
+ break ;
798
+ nBytes = send (pnode->hSocket , reinterpret_cast <const char *>(data.data ()) + pnode->nSendOffset , data.size () - pnode->nSendOffset , MSG_NOSIGNAL | MSG_DONTWAIT);
799
+ }
793
800
if (nBytes > 0 ) {
794
801
pnode->nLastSend = GetSystemTimeInSeconds ();
795
802
pnode->nSendBytes += nBytes;
@@ -1148,12 +1155,6 @@ void CConnman::ThreadSocketHandler()
1148
1155
LOCK (cs_vNodes);
1149
1156
BOOST_FOREACH (CNode* pnode, vNodes)
1150
1157
{
1151
- if (pnode->hSocket == INVALID_SOCKET)
1152
- continue ;
1153
- FD_SET (pnode->hSocket , &fdsetError);
1154
- hSocketMax = std::max (hSocketMax, pnode->hSocket );
1155
- have_fds = true ;
1156
-
1157
1158
// Implement the following logic:
1158
1159
// * If there is data to send, select() for sending data. As this only
1159
1160
// happens when optimistic write failed, we choose to first drain the
@@ -1164,16 +1165,28 @@ void CConnman::ThreadSocketHandler()
1164
1165
// receiving data.
1165
1166
// * Hand off all complete messages to the processor, to be handled without
1166
1167
// blocking here.
1168
+
1169
+ bool select_recv = !pnode->fPauseRecv ;
1170
+ bool select_send;
1167
1171
{
1168
1172
LOCK (pnode->cs_vSend );
1169
- if (!pnode->vSendMsg .empty ()) {
1170
- FD_SET (pnode->hSocket , &fdsetSend);
1171
- continue ;
1172
- }
1173
+ select_send = !pnode->vSendMsg .empty ();
1173
1174
}
1174
- {
1175
- if (!pnode->fPauseRecv )
1176
- FD_SET (pnode->hSocket , &fdsetRecv);
1175
+
1176
+ LOCK (pnode->cs_hSocket );
1177
+ if (pnode->hSocket == INVALID_SOCKET)
1178
+ continue ;
1179
+
1180
+ FD_SET (pnode->hSocket , &fdsetError);
1181
+ hSocketMax = std::max (hSocketMax, pnode->hSocket );
1182
+ have_fds = true ;
1183
+
1184
+ if (select_send) {
1185
+ FD_SET (pnode->hSocket , &fdsetSend);
1186
+ continue ;
1187
+ }
1188
+ if (select_recv) {
1189
+ FD_SET (pnode->hSocket , &fdsetRecv);
1177
1190
}
1178
1191
}
1179
1192
}
@@ -1227,15 +1240,30 @@ void CConnman::ThreadSocketHandler()
1227
1240
//
1228
1241
// Receive
1229
1242
//
1230
- if (pnode->hSocket == INVALID_SOCKET)
1231
- continue ;
1232
- if (FD_ISSET (pnode->hSocket , &fdsetRecv) || FD_ISSET (pnode->hSocket , &fdsetError))
1243
+ bool recvSet = false ;
1244
+ bool sendSet = false ;
1245
+ bool errorSet = false ;
1246
+ {
1247
+ LOCK (pnode->cs_hSocket );
1248
+ if (pnode->hSocket == INVALID_SOCKET)
1249
+ continue ;
1250
+ recvSet = FD_ISSET (pnode->hSocket , &fdsetRecv);
1251
+ sendSet = FD_ISSET (pnode->hSocket , &fdsetSend);
1252
+ errorSet = FD_ISSET (pnode->hSocket , &fdsetError);
1253
+ }
1254
+ if (recvSet || errorSet)
1233
1255
{
1234
1256
{
1235
1257
{
1236
1258
// typical socket buffer is 8K-64K
1237
1259
char pchBuf[0x10000 ];
1238
- int nBytes = recv (pnode->hSocket , pchBuf, sizeof (pchBuf), MSG_DONTWAIT);
1260
+ int nBytes = 0 ;
1261
+ {
1262
+ LOCK (pnode->cs_hSocket );
1263
+ if (pnode->hSocket == INVALID_SOCKET)
1264
+ continue ;
1265
+ nBytes = recv (pnode->hSocket , pchBuf, sizeof (pchBuf), MSG_DONTWAIT);
1266
+ }
1239
1267
if (nBytes > 0 )
1240
1268
{
1241
1269
bool notify = false ;
@@ -1284,9 +1312,7 @@ void CConnman::ThreadSocketHandler()
1284
1312
//
1285
1313
// Send
1286
1314
//
1287
- if (pnode->hSocket == INVALID_SOCKET)
1288
- continue ;
1289
- if (FD_ISSET (pnode->hSocket , &fdsetSend))
1315
+ if (sendSet)
1290
1316
{
1291
1317
LOCK (pnode->cs_vSend );
1292
1318
size_t nBytes = SocketSendData (pnode);
@@ -2275,8 +2301,7 @@ void CConnman::Stop()
2275
2301
2276
2302
// Close sockets
2277
2303
BOOST_FOREACH (CNode* pnode, vNodes)
2278
- if (pnode->hSocket != INVALID_SOCKET)
2279
- CloseSocket (pnode->hSocket );
2304
+ pnode->CloseSocketDisconnect ();
2280
2305
BOOST_FOREACH (ListenSocket& hListenSocket, vhListenSocket)
2281
2306
if (hListenSocket.socket != INVALID_SOCKET)
2282
2307
if (!CloseSocket (hListenSocket.socket ))
@@ -2677,9 +2702,6 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
2677
2702
size_t nBytesSent = 0 ;
2678
2703
{
2679
2704
LOCK (pnode->cs_vSend );
2680
- if (pnode->hSocket == INVALID_SOCKET) {
2681
- return ;
2682
- }
2683
2705
bool optimisticSend (pnode->vSendMsg .empty ());
2684
2706
2685
2707
// log total amount of bytes per command
0 commit comments