Move dead socket cleanup out of the poll() loop

This fixes a potential desync between the fds vector and the connections
map that could happen due to file descriptor number reuse.
This commit is contained in:
dongresource 2023-03-09 22:48:01 +01:00
parent 2bf14200f7
commit abcfa3445b

View File

@ -415,9 +415,9 @@ void CNServer::addPollFD(SOCKET s) {
fds.push_back({s, POLLIN}); fds.push_back({s, POLLIN});
} }
void CNServer::removePollFD(int i) { void CNServer::removePollFD(int fd) {
auto it = fds.begin(); auto it = fds.begin();
while (it != fds.end() && it->fd != fds[i].fd) while (it != fds.end() && it->fd != fd)
it++; it++;
assert(it != fds.end()); assert(it != fds.end());
@ -494,22 +494,29 @@ void CNServer::start() {
if (fds[i].revents & ~POLLIN) if (fds[i].revents & ~POLLIN)
cSock->kill(); cSock->kill();
if (cSock->isAlive()) { if (cSock->isAlive())
cSock->step(); cSock->step();
} else {
killConnection(cSock);
connections.erase(fds[i].fd);
delete cSock;
removePollFD(i);
// a new entry was moved to this position, so we check it again
i--;
}
} }
} }
onStep(); onStep();
// clean up dead connection sockets
auto it = connections.begin();
while (it != connections.end()) {
CNSocket *cSock = it->second;
if (!cSock->isAlive()) {
killConnection(cSock);
it = connections.erase(it);
removePollFD(cSock->sock);
delete cSock;
} else {
it++;
}
}
} }
} }