net: add a lock around hSocket
This commit is contained in:
parent
45e2e08561
commit
9a0b784dea
2 changed files with 29 additions and 15 deletions
33
src/net.cpp
33
src/net.cpp
|
@ -425,6 +425,7 @@ void CConnman::DumpBanlist()
|
||||||
void CNode::CloseSocketDisconnect()
|
void CNode::CloseSocketDisconnect()
|
||||||
{
|
{
|
||||||
fDisconnect = true;
|
fDisconnect = true;
|
||||||
|
LOCK(cs_hSocket);
|
||||||
if (hSocket != INVALID_SOCKET)
|
if (hSocket != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
LogPrint("net", "disconnecting peer=%d\n", id);
|
LogPrint("net", "disconnecting peer=%d\n", id);
|
||||||
|
@ -789,7 +790,13 @@ size_t CConnman::SocketSendData(CNode *pnode) const
|
||||||
while (it != pnode->vSendMsg.end()) {
|
while (it != pnode->vSendMsg.end()) {
|
||||||
const auto &data = *it;
|
const auto &data = *it;
|
||||||
assert(data.size() > pnode->nSendOffset);
|
assert(data.size() > pnode->nSendOffset);
|
||||||
int nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
|
int nBytes = 0;
|
||||||
|
{
|
||||||
|
LOCK(pnode->cs_hSocket);
|
||||||
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
|
break;
|
||||||
|
nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
|
||||||
|
}
|
||||||
if (nBytes > 0) {
|
if (nBytes > 0) {
|
||||||
pnode->nLastSend = GetSystemTimeInSeconds();
|
pnode->nLastSend = GetSystemTimeInSeconds();
|
||||||
pnode->nSendBytes += nBytes;
|
pnode->nSendBytes += nBytes;
|
||||||
|
@ -1150,9 +1157,6 @@ void CConnman::ThreadSocketHandler()
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
if (pnode->hSocket == INVALID_SOCKET)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Implement the following logic:
|
// Implement the following logic:
|
||||||
// * If there is data to send, select() for sending data. As this only
|
// * If there is data to send, select() for sending data. As this only
|
||||||
// happens when optimistic write failed, we choose to first drain the
|
// happens when optimistic write failed, we choose to first drain the
|
||||||
|
@ -1171,6 +1175,10 @@ void CConnman::ThreadSocketHandler()
|
||||||
select_send = !pnode->vSendMsg.empty();
|
select_send = !pnode->vSendMsg.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOCK(pnode->cs_hSocket);
|
||||||
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
|
||||||
FD_SET(pnode->hSocket, &fdsetError);
|
FD_SET(pnode->hSocket, &fdsetError);
|
||||||
hSocketMax = std::max(hSocketMax, pnode->hSocket);
|
hSocketMax = std::max(hSocketMax, pnode->hSocket);
|
||||||
have_fds = true;
|
have_fds = true;
|
||||||
|
@ -1237,18 +1245,27 @@ void CConnman::ThreadSocketHandler()
|
||||||
bool recvSet = false;
|
bool recvSet = false;
|
||||||
bool sendSet = false;
|
bool sendSet = false;
|
||||||
bool errorSet = false;
|
bool errorSet = false;
|
||||||
|
{
|
||||||
|
LOCK(pnode->cs_hSocket);
|
||||||
if (pnode->hSocket == INVALID_SOCKET)
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
continue;
|
continue;
|
||||||
recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
|
recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
|
||||||
sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
|
sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
|
||||||
errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
|
errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
|
||||||
|
}
|
||||||
if (recvSet || errorSet)
|
if (recvSet || errorSet)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
// typical socket buffer is 8K-64K
|
// typical socket buffer is 8K-64K
|
||||||
char pchBuf[0x10000];
|
char pchBuf[0x10000];
|
||||||
int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
int nBytes = 0;
|
||||||
|
{
|
||||||
|
LOCK(pnode->cs_hSocket);
|
||||||
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
||||||
|
}
|
||||||
if (nBytes > 0)
|
if (nBytes > 0)
|
||||||
{
|
{
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
|
@ -2286,8 +2303,7 @@ void CConnman::Stop()
|
||||||
|
|
||||||
// Close sockets
|
// Close sockets
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
if (pnode->hSocket != INVALID_SOCKET)
|
pnode->CloseSocketDisconnect();
|
||||||
CloseSocket(pnode->hSocket);
|
|
||||||
BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
|
BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
|
||||||
if (hListenSocket.socket != INVALID_SOCKET)
|
if (hListenSocket.socket != INVALID_SOCKET)
|
||||||
if (!CloseSocket(hListenSocket.socket))
|
if (!CloseSocket(hListenSocket.socket))
|
||||||
|
@ -2688,9 +2704,6 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
|
||||||
size_t nBytesSent = 0;
|
size_t nBytesSent = 0;
|
||||||
{
|
{
|
||||||
LOCK(pnode->cs_vSend);
|
LOCK(pnode->cs_vSend);
|
||||||
if(pnode->hSocket == INVALID_SOCKET) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool optimisticSend(pnode->vSendMsg.empty());
|
bool optimisticSend(pnode->vSendMsg.empty());
|
||||||
|
|
||||||
//log total amount of bytes per command
|
//log total amount of bytes per command
|
||||||
|
|
|
@ -572,6 +572,7 @@ public:
|
||||||
uint64_t nSendBytes;
|
uint64_t nSendBytes;
|
||||||
std::deque<std::vector<unsigned char>> vSendMsg;
|
std::deque<std::vector<unsigned char>> vSendMsg;
|
||||||
CCriticalSection cs_vSend;
|
CCriticalSection cs_vSend;
|
||||||
|
CCriticalSection cs_hSocket;
|
||||||
|
|
||||||
CCriticalSection cs_vProcessMsg;
|
CCriticalSection cs_vProcessMsg;
|
||||||
std::list<CNetMessage> vProcessMsg;
|
std::list<CNetMessage> vProcessMsg;
|
||||||
|
|
Loading…
Reference in a new issue