Skip to content

Commit

Permalink
馃殌 Added proper server stopping
Browse files Browse the repository at this point in the history
  • Loading branch information
Lygaen committed Feb 9, 2024
1 parent 01f4e1e commit 0602df3
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 8 deletions.
36 changes: 30 additions & 6 deletions src/cmd/console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
#if defined(__linux__)
#include <termios.h>
#include <unistd.h>
#include <pthread.h>
#elif defined(_WIN32)
#include <conio.h>
#include <windows.h>
#endif

ConsoleManager *ConsoleManager::instance;
ConsoleManager::ConsoleManager() : currentInput("")
ConsoleManager::ConsoleManager() : currentInput(""), isRunning(false)
{
if (instance)
throw std::runtime_error("Console handler should not be constructed twice");
Expand Down Expand Up @@ -95,13 +97,35 @@ void ConsoleManager::loop()
}
}

#include <server.h>

void ConsoleManager::start()
{
std::thread([this]()
{ while(true) {
this->loop();
} })
.detach();
std::thread t = std::thread([this]()
{
this->isRunning = true;
while (isRunning)
{
this->loop();
} });
threadHandle = t.native_handle();
t.detach();

CommandsManager::inst().addCommand(
"stop", [](const ISender::SenderType, ISender &, const std::vector<std::string> &)
{ Server::inst()->stop(); },
"", "Stops the server");
}

void ConsoleManager::stop()
{
isRunning = false;

#if defined(__linux__)
pthread_cancel(threadHandle);
#elif defined(_WIN32)
TerminateThread(threadHandle, 1);
#endif
}

void ConsoleManager::onPostPrint(logger::PostPrintEvent event)
Expand Down
8 changes: 8 additions & 0 deletions src/cmd/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define MINESERVER_CONSOLE_H

#include <thread>
#include <atomic>
#include <utils/logger.h>

/**
Expand All @@ -26,6 +27,8 @@ class ConsoleManager

std::string currentInput;
EventHandler<logger::PostPrintEvent>::subId subscribeId;
std::thread::native_handle_type threadHandle;
std::atomic<bool> isRunning;

void loop();

Expand All @@ -46,6 +49,11 @@ class ConsoleManager
*
*/
void start();
/**
* @brief Stops listening for commands
*
*/
void stop();
/**
* @brief Post print hook
*
Expand Down
9 changes: 8 additions & 1 deletion src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
#include <utils/logger.h>
#include <plugins/event.h>
#include <plugins/events/serverevents.hpp>
#include <chrono>

Server *Server::INSTANCE;
Server::Server() : sock(),
connectedClients(),
pluginsManager(),
eventsManager(),
commandsManager(),
consoleManager()
consoleManager(),
isRunning(false)
{
if (INSTANCE)
return;
Expand Down Expand Up @@ -87,11 +89,13 @@ void Server::start()
logger::info("Server started on %s:%d !", addr.c_str(), port);
while (isRunning)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // So that we don't overload the CPU
ClientSocket cs = sock.accept();

if (!cs.isValid())
continue;

// Join thread afterwards
std::thread([&cs, this]()
{
Client client(cs);
Expand All @@ -113,4 +117,7 @@ void Server::stop()
}

sock.close();

consoleManager.stop();
logger::debug("Stopped server !");
}
3 changes: 2 additions & 1 deletion src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <cmd/commands.h>
#include <cmd/console.h>
#include <client.h>
#include <atomic>
#include <list>

/**
Expand All @@ -38,7 +39,7 @@ class Server
CommandsManager commandsManager;
ConsoleManager consoleManager;
ServerSocket sock;
bool isRunning{};
std::atomic<bool> isRunning;

/**
* @brief Internal Checks
Expand Down
7 changes: 7 additions & 0 deletions src/utils/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <WinSock2.h>
#endif // _WIN32
#if defined(__linux__)
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
Expand Down Expand Up @@ -56,6 +57,12 @@ bool ServerSocket::bind(const char *address, int port)
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
}
serv_addr.sin_port = htons(port);
#if defined(__linux__)
fcntl(sock, F_SETFL, O_NONBLOCK);
#elif defined(_WIN32)
u_long mode = 1; // 1 to enable non-blocking socket
ioctlsocket(sock, FIONBIO, &mode);
#endif
int status_code = ::bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
return status_code >= 0;
}
Expand Down

0 comments on commit 0602df3

Please sign in to comment.