From dd6fbfb683862cef3af3189660a016b1f5cf37d8 Mon Sep 17 00:00:00 2001 From: dongresource Date: Sun, 6 Dec 2020 02:20:46 +0100 Subject: [PATCH] Tweak terminate() slightly * Gave it a default argument, since we never actually care about it, but it needs to have it to conform to the signal handler prototype * Constricted the area locked by activeCrit to only the block that deals with the connections vector, to lower the chance of a future badly placed call to terminate() deadlocking the server instead --- src/CNProtocol.cpp | 10 ++++------ src/CNStructs.hpp | 2 +- src/Monitor.cpp | 2 +- src/TableData.cpp | 16 ++++++++-------- src/main.cpp | 4 ++-- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/CNProtocol.cpp b/src/CNProtocol.cpp index 0c7b0ea..eb97818 100644 --- a/src/CNProtocol.cpp +++ b/src/CNProtocol.cpp @@ -313,13 +313,11 @@ void CNServer::start() { int n = poll(fds.data(), fds.size(), 50); if (SOCKETERROR(n)) { std::cout << "[FATAL] poll() returned error" << std::endl; - terminate(0); + terminate(); } oldnfds = fds.size(); - activeCrit.lock(); - for (int i = 0; i < oldnfds && n > 0; i++) { if (fds[i].revents == 0) continue; // nothing in this one; don't decrement n @@ -331,8 +329,7 @@ void CNServer::start() { // any sort of error on the listener if (fds[i].revents & ~POLLIN) { std::cout << "[FATAL] Error on listener socket" << std::endl; - activeCrit.unlock(); // must unlock before calling terminate() - terminate(0); + terminate(); } SOCKET newConnectionSocket = accept(sock, (struct sockaddr *)&address, (socklen_t*)&addressSize); @@ -355,6 +352,8 @@ void CNServer::start() { // no-op. handled in checkExtraSockets(). } else { + std::lock_guard lock(activeCrit); // protect operations on connections + // player sockets if (connections.find(fds[i].fd) == connections.end()) { std::cout << "[WARN] Event on non-existant socket?" << std::endl; @@ -380,7 +379,6 @@ void CNServer::start() { } onStep(); - activeCrit.unlock(); } } diff --git a/src/CNStructs.hpp b/src/CNStructs.hpp index 7f8eb85..c3eb1fc 100644 --- a/src/CNStructs.hpp +++ b/src/CNStructs.hpp @@ -41,7 +41,7 @@ std::string U16toU8(char16_t* src); size_t U8toU16(std::string src, char16_t* des, size_t max); // returns number of char16_t that was written at des time_t getTime(); time_t getTimestamp(); -void terminate(int); +void terminate(int unused=0); // The PROTOCOL_VERSION definition is defined by the build system. #if !defined(PROTOCOL_VERSION) diff --git a/src/Monitor.cpp b/src/Monitor.cpp index 941fc7a..f9e4e52 100644 --- a/src/Monitor.cpp +++ b/src/Monitor.cpp @@ -123,7 +123,7 @@ bool Monitor::acceptConnection(SOCKET fd, uint16_t revents) { if (revents & ~POLLIN) { std::cout << "[FATAL] Error on monitor listener?" << std::endl; - terminate(0); + terminate(); } int sock = accept(listener, (struct sockaddr*)&address, &len); diff --git a/src/TableData.cpp b/src/TableData.cpp index 263fb8f..f58c0cf 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -54,7 +54,7 @@ void TableData::init() { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed NPCs.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } // load everything else from xdttable @@ -230,7 +230,7 @@ void TableData::init() { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed xdt.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } // load temporary mob dump @@ -303,7 +303,7 @@ void TableData::init() { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed mobs.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } loadDrops(); @@ -373,7 +373,7 @@ void TableData::loadPaths(int* nextId) { if (firstPoint["iX"] != pair.second->spawnX || firstPoint["iY"] != pair.second->spawnY) { std::cout << "[FATAL] The first point of the route for mob " << pair.first << " (type " << pair.second->appearanceData.iNPCType << ") does not correspond with its spawn point." << std::endl; - terminate(0); + terminate(); } constructPathNPC(npcPath, pair.first); @@ -386,7 +386,7 @@ void TableData::loadPaths(int* nextId) { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed paths.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } } @@ -497,7 +497,7 @@ void TableData::loadDrops() { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed drops.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } } @@ -539,7 +539,7 @@ void TableData::loadEggs(int32_t* nextId) { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed eggs.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } } @@ -763,7 +763,7 @@ void TableData::loadGruntwork(int32_t *nextId) { } catch (const std::exception& err) { std::cerr << "[FATAL] Malformed gruntwork.json file! Reason:" << err.what() << std::endl; - terminate(0); + terminate(); } } diff --git a/src/main.cpp b/src/main.cpp index df7cd59..35bc13b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,7 +42,7 @@ void startShard(CNShardServer* server) { server->start(); } -// terminate gracefully on SIGINT (for gprof) +// terminate gracefully on SIGINT (for gprof & DB saving) void terminate(int arg) { std::cout << "OpenFusion: terminating." << std::endl; @@ -111,7 +111,7 @@ int main() { case 3: std::cout << "[INFO] Event active. Have a very hoppy Easter!" << std::endl; break; default: std::cout << "[FATAL] Unknown event set in config file." << std::endl; - terminate(0); + terminate(); /* not reached */ }