EmptyEpsilon
EmptyEpsilon copied to clipboard
headless/proxy servers ignore SIGINT, preventing termination with Ctrl+C
The latest version of EmptyEpsilon seems to ignore SIGTERM and SIGINT signals, which prevents "normal" graceful termination via Ctrl+C in the command line, especially when started in headless mode (headless or proxy server).
Currently, the only way of stopping a headless EE server is (hard) killing with SIGKILL (killall -9 EmptyEpsilon).
Only tested on Linux (Debian 11 and Archlinux).
Guess this happened when we moved to SDL2. Not sure how to prevent/fix it. The headless version is a hacky piece of mess...
I just finally upgraded to the current release and finally hit this.
If you've enabled the http server, which is likely for headless, you can stop the server with:
curl --data "shutdownGame()" http://localhost:8080/exec.lua
By default SDL2 converts SIGINT and SIGTERM to SDL_QUIT, and I'm not sure headless/proxy modes handle SDL_QUIT.
SDL_HINT_NO_SIGNAL_HANDLERS configures this, so if I edit SeriousProton/src/engine.cpp to override that:
diff --git a/src/engine.cpp b/src/engine.cpp
index d55dead..f093324 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -61,6 +61,7 @@ Engine::Engine()
}
#endif // WIN32
+ SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1"); // Otherwise, SDL converts SIGINT to SDL_QUIT, which SP doesn't handle
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); // Have clicking on a window to get focus generate mouse events. For multimonitor support.
and rebuild, then SIGINT kills the headless server as expected.
SeriousProton engine.cpp L109-146 contains an if/else that only runs the SDL event queue handling if there's a window (if (Window::all_windows.size() == 0) ... else while(running { SDL_Event event; ...):
void Engine::runMainLoop()
{
if (Window::all_windows.size() == 0)
{
...
}else{
sp::audio::Source::startAudioSystem();
sp::SystemStopwatch frame_timer;
#ifdef DEBUG
sp::SystemTimer debug_output_timer;
debug_output_timer.repeat(5);
#endif
while(running)
{
// Handle events
SDL_Event event;
while (SDL_PollEvent(&event))
{
// we never get here if headless/proxy
handleEvent(event);
}
Filed daid/SeriousProton#217 to handle SDL_QUIT when there's no window.
Noticed this because there's no object count printing every 5 seconds on headless runs of a debug build, which would happen only if that branch of the if statement didn't run in headless mode. (daid/SeriousProton#218)