Integrate the monitor's listener socket into the shard's poll()

This removes the need for a separate monitor thread.
This commit is contained in:
dongresource 2020-12-06 01:44:37 +01:00
parent 53d8cb67ba
commit 92307063fc
7 changed files with 44 additions and 30 deletions

View File

@ -219,7 +219,7 @@ bool setSockNonblocking(SOCKET listener, SOCKET newSock) {
unsigned long mode = 1;
if (ioctlsocket(newSock, FIONBIO, &mode) != 0) {
#else
if (fcntl(newSock, F_SETFL, (fcntl(listener, F_GETFL, 0) | O_NONBLOCK)) != 0) {
if (fcntl(newSock, F_SETFL, (fcntl(newSock, F_GETFL, 0) | O_NONBLOCK)) != 0) {
#endif
std::cerr << "[WARN] OpenFusion: fcntl failed on new connection" << std::endl;
#ifdef _WIN32
@ -351,6 +351,9 @@ void CNServer::start() {
connections[newConnectionSocket] = tmp;
newConnection(tmp);
} else if (checkExtraSockets(i)) {
// no-op. handled in checkExtraSockets().
} else {
// player sockets
if (connections.find(fds[i].fd) == connections.end()) {
@ -419,6 +422,7 @@ void CNServer::printPacket(CNPacketData *data, int type) {
std::cout << "OpenFusion: received " << Defines::p2str(type, data->type) << " (" << data->type << ")" << std::endl;
}
bool CNServer::checkExtraSockets(int i) { return false; } // stubbed
void CNServer::newConnection(CNSocket* cns) {} // stubbed
void CNServer::killConnection(CNSocket* cns) {} // stubbed
void CNServer::onStep() {} // stubbed

View File

@ -223,6 +223,7 @@ public:
void start();
void kill();
static void printPacket(CNPacketData *data, int type);
virtual bool checkExtraSockets(int i);
virtual void newConnection(CNSocket* cns);
virtual void killConnection(CNSocket* cns);
virtual void onStep();

View File

@ -6,6 +6,7 @@
#include "CNShared.hpp"
#include "settings.hpp"
#include "Database.hpp"
#include "Monitor.hpp"
#include "TableData.hpp" // for flush()
#include <iostream>
@ -21,6 +22,9 @@ CNShardServer::CNShardServer(uint16_t p) {
REGISTER_SHARD_TIMER(keepAliveTimer, 4000);
REGISTER_SHARD_TIMER(periodicSaveTimer, settings::DBSAVEINTERVAL*1000);
init();
if (settings::MONITORENABLED)
fds.push_back({Monitor::init(), POLLIN});
}
void CNShardServer::handlePacket(CNSocket* sock, CNPacketData* data) {
@ -62,6 +66,10 @@ void CNShardServer::periodicSaveTimer(CNServer* serv, time_t currTime) {
std::cout << "[INFO] Done." << std::endl;
}
bool CNShardServer::checkExtraSockets(int i) {
return Monitor::acceptConnection(fds[i].fd, fds[i].revents);
}
void CNShardServer::newConnection(CNSocket* cns) {
cns->setActiveKey(SOCKETKEY_E); // by default they accept keys encrypted with the default key
}

View File

@ -23,6 +23,7 @@ public:
static void _killConnection(CNSocket *cns);
bool checkExtraSockets(int i);
void newConnection(CNSocket* cns);
void killConnection(CNSocket* cns);
void kill();

View File

@ -6,16 +6,12 @@
#include <cstdio>
static int listener;
static SOCKET listener;
static std::mutex sockLock; // guards socket list
static std::list<SOCKET> sockets;
static sockaddr_in address;
// runs during init
void Monitor::init() {
if (!settings::MONITORENABLED)
return;
SOCKET Monitor::init() {
listener = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKETERROR(listener)) {
std::cout << "Failed to create monitor socket" << std::endl;
@ -59,6 +55,8 @@ void Monitor::init() {
std::cout << "Monitor listening on *:" << settings::MONITORPORT << std::endl;
REGISTER_SHARD_TIMER(tick, settings::MONITORINTERVAL);
return listener;
}
static bool transmit(std::list<SOCKET>::iterator& it, char *buff, int len) {
@ -86,7 +84,6 @@ static bool transmit(std::list<SOCKET>::iterator& it, char *buff, int len) {
return true;
}
// runs in shard thread
void Monitor::tick(CNServer *serv, time_t delta) {
std::lock_guard<std::mutex> lock(sockLock);
char buff[256];
@ -115,26 +112,33 @@ void Monitor::tick(CNServer *serv, time_t delta) {
}
}
// runs in monitor thread
void Monitor::start(void *unused) {
bool Monitor::acceptConnection(SOCKET fd, uint16_t revents) {
socklen_t len = sizeof(address);
if (!settings::MONITORENABLED)
return;
return false;
for (;;) {
int sock = accept(listener, (struct sockaddr*)&address, &len);
if (SOCKETERROR(sock))
continue;
if (fd != listener)
return false;
setSockNonblocking(listener, sock);
std::cout << "[INFO] New monitor connection from " << inet_ntoa(address.sin_addr) << std::endl;
{
std::lock_guard<std::mutex> lock(sockLock);
sockets.push_back(sock);
}
if (revents & ~POLLIN) {
std::cout << "[FATAL] Error on monitor listener?" << std::endl;
terminate(0);
}
int sock = accept(listener, (struct sockaddr*)&address, &len);
if (SOCKETERROR(sock))
return true;
setSockNonblocking(listener, sock);
std::cout << "[INFO] New monitor connection from " << inet_ntoa(address.sin_addr) << std::endl;
{
std::lock_guard<std::mutex> lock(sockLock);
sockets.push_back(sock);
}
return true;
}

View File

@ -6,7 +6,7 @@
#include <mutex>
namespace Monitor {
void init();
SOCKET init();
void tick(CNServer *, time_t);
void start(void *);
bool acceptConnection(SOCKET, uint16_t);
};

View File

@ -38,8 +38,6 @@
CNShardServer *shardServer = nullptr;
std::thread *shardThread = nullptr;
std::thread *monitorThread = nullptr;
void startShard(CNShardServer* server) {
server->start();
}
@ -104,7 +102,6 @@ int main() {
TransportManager::init();
BuddyManager::init();
GroupManager::init();
Monitor::init();
Database::open();
switch (settings::EVENTMODE) {
@ -123,7 +120,6 @@ int main() {
shardServer = new CNShardServer(settings::SHARDPORT);
shardThread = new std::thread(startShard, (CNShardServer*)shardServer);
monitorThread = new std::thread(Monitor::start, nullptr);
loginServer.start();