| 2145 | } |
| 2146 | |
| 2147 | void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes, |
| 2148 | const Sock::EventsPerSock& events_per_sock) |
| 2149 | { |
| 2150 | AssertLockNotHeld(m_total_bytes_sent_mutex); |
| 2151 | |
| 2152 | const auto now{NodeClock::now()}; |
| 2153 | |
| 2154 | for (CNode* pnode : nodes) { |
| 2155 | if (m_interrupt_net->interrupted()) { |
| 2156 | return; |
| 2157 | } |
| 2158 | |
| 2159 | // |
| 2160 | // Receive |
| 2161 | // |
| 2162 | bool recvSet = false; |
| 2163 | bool sendSet = false; |
| 2164 | bool errorSet = false; |
| 2165 | { |
| 2166 | LOCK(pnode->m_sock_mutex); |
| 2167 | if (!pnode->m_sock) { |
| 2168 | continue; |
| 2169 | } |
| 2170 | const auto it = events_per_sock.find(pnode->m_sock); |
| 2171 | if (it != events_per_sock.end()) { |
| 2172 | recvSet = it->second.occurred & Sock::RecvEvent; |
| 2173 | sendSet = it->second.occurred & Sock::SendEvent; |
| 2174 | errorSet = it->second.occurred & Sock::ErrorEvent; |
| 2175 | } |
| 2176 | } |
| 2177 | |
| 2178 | if (sendSet) { |
| 2179 | // Send data |
| 2180 | auto [bytes_sent, data_left] = WITH_LOCK(pnode->cs_vSend, return SocketSendData(*pnode)); |
| 2181 | if (bytes_sent) { |
| 2182 | RecordBytesSent(bytes_sent); |
| 2183 | |
| 2184 | // If both receiving and (non-optimistic) sending were possible, we first attempt |
| 2185 | // sending. If that succeeds, but does not fully drain the send queue, do not |
| 2186 | // attempt to receive. This avoids needlessly queueing data if the remote peer |
| 2187 | // is slow at receiving data, by means of TCP flow control. We only do this when |
| 2188 | // sending actually succeeded to make sure progress is always made; otherwise a |
| 2189 | // deadlock would be possible when both sides have data to send, but neither is |
| 2190 | // receiving. |
| 2191 | if (data_left) recvSet = false; |
| 2192 | } |
| 2193 | } |
| 2194 | |
| 2195 | if (recvSet || errorSet) |
| 2196 | { |
| 2197 | // typical socket buffer is 8K-64K |
| 2198 | uint8_t pchBuf[0x10000]; |
| 2199 | int nBytes = 0; |
| 2200 | { |
| 2201 | LOCK(pnode->m_sock_mutex); |
| 2202 | if (!pnode->m_sock) { |
| 2203 | continue; |
| 2204 | } |
nothing calls this directly
no test coverage detected