De asemenea, salvarea progresului este mult mai precisă, fără delay-ul din command prompt/bash, iar activitatea poate fi reluată imediat, fără întreruperi.
Aceste îmbunătățiri vor ajuta la o gestionare mai rapidă și sigură a serverului!
libthecore/src/signal.c
Code:
#define __LIBTHECORE__
#include "stdafx.h"
#include "globals.h"
#ifdef __WIN32__
#include <windows.h>
int esc_count = 0;
DWORD lastEscPressTime = 0;
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
//case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
printf("Graceful shutdown signal received. Shutting down.\n");
shutdowned = TRUE;
break;
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
printf("Forceful exit signal received. Shutting down instantly.\n");
shutdowned = TRUE;
break;
default:
return FALSE;
}
return TRUE;
}
DWORD WINAPI EscKeyListener(LPVOID lpParam)
{
int combo_count = 0;
DWORD lastPressTime = 0;
DWORD resetTime = 2000;
while (!shutdowned)
{
if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && (GetAsyncKeyState(VK_ESCAPE) & 0x8000))
{
DWORD currentTime = GetTickCount();
if (currentTime - lastPressTime > resetTime)
{
combo_count = 0;
printf("Timeout exceeded. Resetting combo count.\n");
}
combo_count++;
printf("Ctrl+ESC combo pressed %d time(s)\n", combo_count);
if (combo_count >= 3)
{
printf("Ctrl+ESC pressed 3 times. Shutting down server.\n");
shutdowned = TRUE;
}
lastPressTime = currentTime;
while ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && (GetAsyncKeyState(VK_ESCAPE) & 0x8000))
{
Sleep(10);
}
}
Sleep(10);
}
ExitProcess(0);
return 0;
}
void signal_setup()
{
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
{
printf("Error setting control handler.\n");
}
HANDLE escThread = CreateThread(NULL, 0, EscKeyListener, NULL, 0, NULL);
if (escThread == NULL)
{
printf("Error creating ESC key listener thread.\n");
}
else
{
CloseHandle(escThread);
}
}
void signal_timer_disable() {}
void signal_timer_enable(int timeout_seconds) {}
#elif __FreeBSD__
#define RETSIGTYPE void
RETSIGTYPE reap(int sig)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
signal(SIGCHLD, reap);
}
RETSIGTYPE checkpointing(int sig)
{
if (!tics)
{
sys_err("CHECKPOINT shutdown: tics did not update.");
if (bCheckpointCheck)
abort();
}
else
tics = 0;
}
RETSIGTYPE hupsig(int sig)
{
shutdowned = TRUE;
sys_log(0, "SIGHUP, SIGINT, SIGTERM signal has been received. Shutting down.");
}
RETSIGTYPE usrsig(int sig)
{
core_dump();
}
void signal_timer_disable(void)
{
struct itimerval itime;
struct timeval interval;
interval.tv_sec = 0;
interval.tv_usec = 0;
itime.it_interval = interval;
itime.it_value = interval;
setitimer(ITIMER_VIRTUAL, &itime, NULL);
}
void signal_timer_enable(int sec)
{
struct itimerval itime;
struct timeval interval;
interval.tv_sec = sec;
interval.tv_usec = 0;
itime.it_interval = interval;
itime.it_value = interval;
setitimer(ITIMER_VIRTUAL, &itime, NULL);
}
void signal_setup(void)
{
signal_timer_enable(30);
signal(SIGVTALRM, checkpointing);
// Just to be on the safe side:
signal(SIGHUP, hupsig);
signal(SIGCHLD, reap);
signal(SIGINT, hupsig);
signal(SIGTERM, hupsig);
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, SIG_IGN);
signal(SIGUSR1, usrsig);
}
#endif
Pune aceste fisiere in libthecore/src