Skip to content

Commit 9d47d6d

Browse files
committed
Move cs_vSend lock into SocketSendData
SocketSendData requires cs_vSend to be locked, but it places this responsibility with the caller. This is unnecessary, unclear, and has caused us to accidentally add RecordBytesSent under the lock. This commit fixes both problems. Justification is needed in the case of PushMessage. It is ok that we let go of cs_vSend for a moment before locking it again and calling SocketSendData. In the case where optimistic_send == false, this lock is let go of for a long time between adding messages to vSendMsg and the call to SocketSendData (in SocketHandler). As corrected in the comment change, optimistic_send represents whether vSendMsg *was* empty, not *is* empty (as, of course, we've just added to it). If SocketHandler grabs cs_vSend in the middle then SocketSendData will be empty when we call it in PushMessage. As suggested by the "if (bytes_sent)" check, this is fine.
1 parent 92897d4 commit 9d47d6d

File tree

1 file changed

+11
-14
lines changed

1 file changed

+11
-14
lines changed

src/net.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,9 @@ void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vec
747747
CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, header, 0, hdr};
748748
}
749749

750-
size_t CConnman::SocketSendData(CNode *pnode) const EXCLUSIVE_LOCKS_REQUIRED(pnode->cs_vSend)
750+
size_t CConnman::SocketSendData(CNode *pnode) const
751751
{
752+
LOCK(pnode->cs_vSend);
752753
auto it = pnode->vSendMsg.begin();
753754
size_t nSentSize = 0;
754755

@@ -1445,11 +1446,8 @@ void CConnman::SocketHandler()
14451446
//
14461447
if (sendSet)
14471448
{
1448-
LOCK(pnode->cs_vSend);
1449-
size_t nBytes = SocketSendData(pnode);
1450-
if (nBytes) {
1451-
RecordBytesSent(nBytes);
1452-
}
1449+
const size_t bytes_sent{SocketSendData(pnode)};
1450+
if (bytes_sent) RecordBytesSent(bytes_sent);
14531451
}
14541452

14551453
InactivityCheck(pnode);
@@ -2821,10 +2819,10 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
28212819
pnode->m_serializer->prepareForTransport(msg, serialized_header);
28222820
const size_t total_size{message_size + serialized_header.size()};
28232821

2824-
size_t bytes_sent{0};
2822+
bool optimistic_send{false};
28252823
{
28262824
LOCK(pnode->cs_vSend);
2827-
bool optimistic_send{pnode->vSendMsg.empty()};
2825+
optimistic_send = pnode->vSendMsg.empty();
28282826

28292827
//log total amount of bytes per message type
28302828
pnode->mapSendBytesPerMsgCmd[msg.m_type] += total_size;
@@ -2837,13 +2835,12 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
28372835
if (message_size) {
28382836
pnode->vSendMsg.push_back(std::move(msg.data));
28392837
}
2840-
2841-
// If write queue empty, attempt "optimistic write"
2842-
if (optimistic_send) {
2843-
bytes_sent = SocketSendData(pnode);
2844-
}
28452838
}
2846-
if (bytes_sent) RecordBytesSent(bytes_sent);
2839+
// If write queue was empty, attempt "optimistic write"
2840+
if (optimistic_send) {
2841+
const size_t bytes_sent{SocketSendData(pnode)};
2842+
if (bytes_sent) RecordBytesSent(bytes_sent);
2843+
}
28472844
}
28482845

28492846
bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)

0 commit comments

Comments
 (0)