@@ -1395,13 +1395,12 @@ bool CConnman::InactivityCheck(const CNode& node) const
1395
1395
return false ;
1396
1396
}
1397
1397
1398
- bool CConnman::GenerateSelectSet (const std::vector<CNode*>& nodes,
1399
- std::set<SOCKET>& recv_set,
1400
- std::set<SOCKET>& send_set,
1401
- std::set<SOCKET>& error_set)
1398
+ Sock::EventsPerSock CConnman::GenerateWaitSockets (Span<CNode* const > nodes)
1402
1399
{
1400
+ Sock::EventsPerSock events_per_sock;
1401
+
1403
1402
for (const ListenSocket& hListenSocket : vhListenSocket) {
1404
- recv_set. insert (hListenSocket.sock -> Get () );
1403
+ events_per_sock. emplace (hListenSocket.sock , Sock::Events{Sock::RECV} );
1405
1404
}
1406
1405
1407
1406
for (CNode* pnode : nodes) {
@@ -1428,172 +1427,49 @@ bool CConnman::GenerateSelectSet(const std::vector<CNode*>& nodes,
1428
1427
continue ;
1429
1428
}
1430
1429
1431
- error_set. insert (pnode-> m_sock -> Get ()) ;
1430
+ Sock::Event requested{ 0 } ;
1432
1431
if (select_send) {
1433
- send_set.insert (pnode->m_sock ->Get ());
1434
- continue ;
1435
- }
1436
- if (select_recv) {
1437
- recv_set.insert (pnode->m_sock ->Get ());
1438
- }
1439
- }
1440
-
1441
- return !recv_set.empty () || !send_set.empty () || !error_set.empty ();
1442
- }
1443
-
1444
- #ifdef USE_POLL
1445
- void CConnman::SocketEvents (const std::vector<CNode*>& nodes,
1446
- std::set<SOCKET>& recv_set,
1447
- std::set<SOCKET>& send_set,
1448
- std::set<SOCKET>& error_set)
1449
- {
1450
- std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1451
- if (!GenerateSelectSet (nodes, recv_select_set, send_select_set, error_select_set)) {
1452
- interruptNet.sleep_for (std::chrono::milliseconds (SELECT_TIMEOUT_MILLISECONDS));
1453
- return ;
1454
- }
1455
-
1456
- std::unordered_map<SOCKET, struct pollfd > pollfds;
1457
- for (SOCKET socket_id : recv_select_set) {
1458
- pollfds[socket_id].fd = socket_id;
1459
- pollfds[socket_id].events |= POLLIN;
1460
- }
1461
-
1462
- for (SOCKET socket_id : send_select_set) {
1463
- pollfds[socket_id].fd = socket_id;
1464
- pollfds[socket_id].events |= POLLOUT;
1465
- }
1466
-
1467
- for (SOCKET socket_id : error_select_set) {
1468
- pollfds[socket_id].fd = socket_id;
1469
- // These flags are ignored, but we set them for clarity
1470
- pollfds[socket_id].events |= POLLERR|POLLHUP;
1471
- }
1472
-
1473
- std::vector<struct pollfd > vpollfds;
1474
- vpollfds.reserve (pollfds.size ());
1475
- for (auto it : pollfds) {
1476
- vpollfds.push_back (std::move (it.second ));
1477
- }
1478
-
1479
- if (poll (vpollfds.data (), vpollfds.size (), SELECT_TIMEOUT_MILLISECONDS) < 0 ) return ;
1480
-
1481
- if (interruptNet) return ;
1482
-
1483
- for (struct pollfd pollfd_entry : vpollfds) {
1484
- if (pollfd_entry.revents & POLLIN) recv_set.insert (pollfd_entry.fd );
1485
- if (pollfd_entry.revents & POLLOUT) send_set.insert (pollfd_entry.fd );
1486
- if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert (pollfd_entry.fd );
1487
- }
1488
- }
1489
- #else
1490
- void CConnman::SocketEvents (const std::vector<CNode*>& nodes,
1491
- std::set<SOCKET>& recv_set,
1492
- std::set<SOCKET>& send_set,
1493
- std::set<SOCKET>& error_set)
1494
- {
1495
- std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1496
- if (!GenerateSelectSet (nodes, recv_select_set, send_select_set, error_select_set)) {
1497
- interruptNet.sleep_for (std::chrono::milliseconds (SELECT_TIMEOUT_MILLISECONDS));
1498
- return ;
1499
- }
1500
-
1501
- //
1502
- // Find which sockets have data to receive
1503
- //
1504
- struct timeval timeout;
1505
- timeout.tv_sec = 0 ;
1506
- timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000 ; // frequency to poll pnode->vSend
1507
-
1508
- fd_set fdsetRecv;
1509
- fd_set fdsetSend;
1510
- fd_set fdsetError;
1511
- FD_ZERO (&fdsetRecv);
1512
- FD_ZERO (&fdsetSend);
1513
- FD_ZERO (&fdsetError);
1514
- SOCKET hSocketMax = 0 ;
1515
-
1516
- for (SOCKET hSocket : recv_select_set) {
1517
- FD_SET (hSocket, &fdsetRecv);
1518
- hSocketMax = std::max (hSocketMax, hSocket);
1519
- }
1520
-
1521
- for (SOCKET hSocket : send_select_set) {
1522
- FD_SET (hSocket, &fdsetSend);
1523
- hSocketMax = std::max (hSocketMax, hSocket);
1524
- }
1525
-
1526
- for (SOCKET hSocket : error_select_set) {
1527
- FD_SET (hSocket, &fdsetError);
1528
- hSocketMax = std::max (hSocketMax, hSocket);
1529
- }
1530
-
1531
- int nSelect = select (hSocketMax + 1 , &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1532
-
1533
- if (interruptNet)
1534
- return ;
1535
-
1536
- if (nSelect == SOCKET_ERROR)
1537
- {
1538
- int nErr = WSAGetLastError ();
1539
- LogPrintf (" socket select error %s\n " , NetworkErrorString (nErr));
1540
- for (unsigned int i = 0 ; i <= hSocketMax; i++)
1541
- FD_SET (i, &fdsetRecv);
1542
- FD_ZERO (&fdsetSend);
1543
- FD_ZERO (&fdsetError);
1544
- if (!interruptNet.sleep_for (std::chrono::milliseconds (SELECT_TIMEOUT_MILLISECONDS)))
1545
- return ;
1546
- }
1547
-
1548
- for (SOCKET hSocket : recv_select_set) {
1549
- if (FD_ISSET (hSocket, &fdsetRecv)) {
1550
- recv_set.insert (hSocket);
1432
+ requested = Sock::SEND;
1433
+ } else if (select_recv) {
1434
+ requested = Sock::RECV;
1551
1435
}
1552
- }
1553
1436
1554
- for (SOCKET hSocket : send_select_set) {
1555
- if (FD_ISSET (hSocket, &fdsetSend)) {
1556
- send_set.insert (hSocket);
1557
- }
1437
+ events_per_sock.emplace (pnode->m_sock , Sock::Events{requested});
1558
1438
}
1559
1439
1560
- for (SOCKET hSocket : error_select_set) {
1561
- if (FD_ISSET (hSocket, &fdsetError)) {
1562
- error_set.insert (hSocket);
1563
- }
1564
- }
1440
+ return events_per_sock;
1565
1441
}
1566
- #endif
1567
1442
1568
1443
void CConnman::SocketHandler ()
1569
1444
{
1570
1445
AssertLockNotHeld (m_total_bytes_sent_mutex);
1571
1446
1572
- std::set<SOCKET> recv_set;
1573
- std::set<SOCKET> send_set;
1574
- std::set<SOCKET> error_set;
1447
+ Sock::EventsPerSock events_per_sock;
1575
1448
1576
1449
{
1577
1450
const NodesSnapshot snap{*this , /* shuffle=*/ false };
1578
1451
1452
+ const auto timeout = std::chrono::milliseconds (SELECT_TIMEOUT_MILLISECONDS);
1453
+
1579
1454
// Check for the readiness of the already connected sockets and the
1580
1455
// listening sockets in one call ("readiness" as in poll(2) or
1581
1456
// select(2)). If none are ready, wait for a short while and return
1582
1457
// empty sets.
1583
- SocketEvents (snap.Nodes (), recv_set, send_set, error_set);
1458
+ events_per_sock = GenerateWaitSockets (snap.Nodes ());
1459
+ if (events_per_sock.empty () || !events_per_sock.begin ()->first ->WaitMany (timeout, events_per_sock)) {
1460
+ interruptNet.sleep_for (timeout);
1461
+ }
1584
1462
1585
1463
// Service (send/receive) each of the already connected nodes.
1586
- SocketHandlerConnected (snap.Nodes (), recv_set, send_set, error_set );
1464
+ SocketHandlerConnected (snap.Nodes (), events_per_sock );
1587
1465
}
1588
1466
1589
1467
// Accept new connections from listening sockets.
1590
- SocketHandlerListening (recv_set );
1468
+ SocketHandlerListening (events_per_sock );
1591
1469
}
1592
1470
1593
1471
void CConnman::SocketHandlerConnected (const std::vector<CNode*>& nodes,
1594
- const std::set<SOCKET>& recv_set,
1595
- const std::set<SOCKET>& send_set,
1596
- const std::set<SOCKET>& error_set)
1472
+ const Sock::EventsPerSock& events_per_sock)
1597
1473
{
1598
1474
AssertLockNotHeld (m_total_bytes_sent_mutex);
1599
1475
@@ -1612,9 +1488,12 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
1612
1488
if (!pnode->m_sock ) {
1613
1489
continue ;
1614
1490
}
1615
- recvSet = recv_set.count (pnode->m_sock ->Get ()) > 0 ;
1616
- sendSet = send_set.count (pnode->m_sock ->Get ()) > 0 ;
1617
- errorSet = error_set.count (pnode->m_sock ->Get ()) > 0 ;
1491
+ const auto it = events_per_sock.find (pnode->m_sock );
1492
+ if (it != events_per_sock.end ()) {
1493
+ recvSet = it->second .occurred & Sock::RECV;
1494
+ sendSet = it->second .occurred & Sock::SEND;
1495
+ errorSet = it->second .occurred & Sock::ERR;
1496
+ }
1618
1497
}
1619
1498
if (recvSet || errorSet)
1620
1499
{
@@ -1684,13 +1563,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
1684
1563
}
1685
1564
}
1686
1565
1687
- void CConnman::SocketHandlerListening (const std::set<SOCKET>& recv_set )
1566
+ void CConnman::SocketHandlerListening (const Sock::EventsPerSock& events_per_sock )
1688
1567
{
1689
1568
for (const ListenSocket& listen_socket : vhListenSocket) {
1690
1569
if (interruptNet) {
1691
1570
return ;
1692
1571
}
1693
- if (recv_set.count (listen_socket.sock ->Get ()) > 0 ) {
1572
+ const auto it = events_per_sock.find (listen_socket.sock );
1573
+ if (it != events_per_sock.end () && it->second .occurred & Sock::RECV) {
1694
1574
AcceptConnection (listen_socket);
1695
1575
}
1696
1576
}
0 commit comments