Revert "CNServer::start() now uses an iterator instead of indexing repeatedly"

This change subtly broke the poll() loop when a connection was removed,
because erasing an entry from fds would invalidate the iterator that
was still being used.

This reverts commit ec67cc6527.
This commit is contained in:
dongresource 2021-03-31 21:07:47 +02:00
parent 919c14be0d
commit 7c7d9f1be8
1 changed files with 8 additions and 11 deletions

View File

@ -363,18 +363,15 @@ void CNServer::start() {
} }
for (int i = 0; i < fds.size() && n > 0; i++) { for (int i = 0; i < fds.size() && n > 0; i++) {
// about the same as fds[i], O(1) if (fds[i].revents == 0)
std::vector<PollFD>::iterator iter = fds.begin() + i;
if ((*iter).revents == 0)
continue; // nothing in this one; don't decrement n continue; // nothing in this one; don't decrement n
n--; n--;
// is it the listener? // is it the listener?
if ((*iter).fd == sock) { if (fds[i].fd == sock) {
// any sort of error on the listener // any sort of error on the listener
if ((*iter).revents & ~POLLIN) { if (fds[i].revents & ~POLLIN) {
std::cout << "[FATAL] Error on listener socket" << std::endl; std::cout << "[FATAL] Error on listener socket" << std::endl;
terminate(0); terminate(0);
} }
@ -404,25 +401,25 @@ void CNServer::start() {
std::lock_guard<std::mutex> lock(activeCrit); // protect operations on connections std::lock_guard<std::mutex> lock(activeCrit); // protect operations on connections
// player sockets // player sockets
if (connections.find((*iter).fd) == connections.end()) { if (connections.find(fds[i].fd) == connections.end()) {
std::cout << "[WARN] Event on non-existant socket?" << std::endl; std::cout << "[WARN] Event on non-existant socket?" << std::endl;
continue; // just to be safe continue; // just to be safe
} }
CNSocket* cSock = connections[(*iter).fd]; CNSocket* cSock = connections[fds[i].fd];
// kill the socket on hangup/error // kill the socket on hangup/error
if ((*iter).revents & ~POLLIN) if (fds[i].revents & ~POLLIN)
cSock->kill(); cSock->kill();
if (cSock->isAlive()) { if (cSock->isAlive()) {
cSock->step(); cSock->step();
} else { } else {
killConnection(cSock); killConnection(cSock);
connections.erase((*iter).fd); connections.erase(fds[i].fd);
delete cSock; delete cSock;
fds.erase(iter); removePollFD(i);
// a new entry was moved to this position, so we check it again // a new entry was moved to this position, so we check it again
i--; i--;