Fix exit behaviour

We can't rely on atexit, handlers registered with it are in a hard to establish ordering relationship with destructors of static and thread-local objects.
This commit is contained in:
Tamás Bálint Misius 2023-01-26 11:38:17 +01:00
parent 11945ba620
commit 694bc8eb0f
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
10 changed files with 62 additions and 37 deletions

View File

@ -123,7 +123,7 @@ void BlueScreen(String detailMessage)
{ {
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
if(event.type == SDL_QUIT) if(event.type == SDL_QUIT)
exit(-1); exit(-1); // Don't use Platform::Exit, we're practically zombies at this point anyway.
blit(engine.g->vid); blit(engine.g->vid);
} }
} }
@ -181,21 +181,9 @@ static std::unique_ptr<ExplicitSingletons> explicitSingletons;
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
Platform::SetupCrt(); Platform::SetupCrt();
atexit([]() { Platform::Atexit([]() {
ui::Engine::Ref().CloseWindow(); SDLClose();
explicitSingletons.reset(); explicitSingletons.reset();
if (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_OPENGL)
{
// * nvidia-460 egl registers callbacks with x11 that end up being called
// after egl is unloaded unless we grab it here and release it after
// sdl closes the display. this is an nvidia driver weirdness but
// technically an sdl bug. glfw has this fixed:
// https://github.com/glfw/glfw/commit/9e6c0c747be838d1f3dc38c2924a47a42416c081
SDL_GL_LoadLibrary(NULL);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_GL_UnloadLibrary();
}
SDL_Quit();
}); });
explicitSingletons = std::make_unique<ExplicitSingletons>(); explicitSingletons = std::make_unique<ExplicitSingletons>();
@ -318,7 +306,7 @@ int main(int argc, char * argv[])
FILE *new_stderr = freopen("stderr.log", "w", stderr); FILE *new_stderr = freopen("stderr.log", "w", stderr);
if (!new_stdout || !new_stderr) if (!new_stdout || !new_stderr)
{ {
exit(42); Platform::Exit(42);
} }
} }
@ -522,5 +510,6 @@ int main(int argc, char * argv[])
{ {
wrapWithBluescreen(); wrapWithBluescreen();
} }
Platform::Exit(0);
return 0; return 0;
} }

View File

@ -36,21 +36,9 @@ static std::unique_ptr<ExplicitSingletons> explicitSingletons;
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
Platform::SetupCrt(); Platform::SetupCrt();
atexit([]() { Platform::Atexit([]() {
ui::Engine::Ref().CloseWindow(); SDLClose();
explicitSingletons.reset(); explicitSingletons.reset();
if (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_OPENGL)
{
// * nvidia-460 egl registers callbacks with x11 that end up being called
// after egl is unloaded unless we grab it here and release it after
// sdl closes the display. this is an nvidia driver weirdness but
// technically an sdl bug. glfw has this fixed:
// https://github.com/glfw/glfw/commit/9e6c0c747be838d1f3dc38c2924a47a42416c081
SDL_GL_LoadLibrary(NULL);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_GL_UnloadLibrary();
}
SDL_Quit();
}); });
explicitSingletons = std::make_unique<ExplicitSingletons>(); explicitSingletons = std::make_unique<ExplicitSingletons>();
@ -99,9 +87,10 @@ int main(int argc, char * argv[])
else else
{ {
std::cerr << "path to font.cpp not supplied" << std::endl; std::cerr << "path to font.cpp not supplied" << std::endl;
exit(1); Platform::Exit(1);
} }
EngineProcess(); EngineProcess();
Platform::Exit(0);
return 0; return 0;
} }

View File

@ -4,6 +4,7 @@
#include "Config.h" #include "Config.h"
#include "gui/interface/Engine.h" #include "gui/interface/Engine.h"
#include "graphics/Graphics.h" #include "graphics/Graphics.h"
#include "common/Platform.h"
#include <iostream> #include <iostream>
int desktopWidth = 1280; int desktopWidth = 1280;
@ -96,13 +97,13 @@ void SDLOpen()
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
{ {
fprintf(stderr, "Initializing SDL (video subsystem): %s\n", SDL_GetError()); fprintf(stderr, "Initializing SDL (video subsystem): %s\n", SDL_GetError());
exit(-1); Platform::Exit(-1);
} }
if (!RecreateWindow()) if (!RecreateWindow())
{ {
fprintf(stderr, "Creating SDL window: %s\n", SDL_GetError()); fprintf(stderr, "Creating SDL window: %s\n", SDL_GetError());
exit(-1); Platform::Exit(-1);
} }
int displayIndex = SDL_GetWindowDisplayIndex(sdl_window); int displayIndex = SDL_GetWindowDisplayIndex(sdl_window);
@ -122,6 +123,22 @@ void SDLOpen()
} }
} }
void SDLClose()
{
if (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_OPENGL)
{
// * nvidia-460 egl registers callbacks with x11 that end up being called
// after egl is unloaded unless we grab it here and release it after
// sdl closes the display. this is an nvidia driver weirdness but
// technically an sdl bug. glfw has this fixed:
// https://github.com/glfw/glfw/commit/9e6c0c747be838d1f3dc38c2924a47a42416c081
SDL_GL_LoadLibrary(NULL);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
SDL_GL_UnloadLibrary();
}
SDL_Quit();
}
void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_) void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_)
{ {
// bool changingScale = scale != scale_; // bool changingScale = scale != scale_;

View File

@ -37,6 +37,7 @@ unsigned int GetTicks();
void CalculateMousePosition(int *x, int *y); void CalculateMousePosition(int *x, int *y);
void blit(pixel *vid); void blit(pixel *vid);
void SDLOpen(); void SDLOpen();
void SDLClose();
void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_); void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_);
bool RecreateWindow(); bool RecreateWindow();
void LoadWindowPosition(); void LoadWindowPosition();

View File

@ -975,7 +975,7 @@ void bson_fatal_msg( int ok , const char *msg ) {
} }
bson_errprintf( "error: %s\n" , msg ); bson_errprintf( "error: %s\n" , msg );
exit( -5 ); abort();
} }

View File

@ -3,6 +3,7 @@
#include "tpt-rand.h" #include "tpt-rand.h"
#include "Config.h" #include "Config.h"
#include <memory> #include <memory>
#include <list>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@ -106,4 +107,20 @@ bool WriteFile(const std::vector<char> &fileData, ByteString filename)
} }
return true; return true;
} }
std::list<ExitFunc> exitFuncs;
void Atexit(ExitFunc exitFunc)
{
exitFuncs.push_front(exitFunc);
}
void Exit(int code)
{
for (auto exitFunc : exitFuncs)
{
exitFunc();
}
exit(code);
}
} }

View File

@ -55,4 +55,8 @@ namespace Platform
void UpdateCleanup(); void UpdateCleanup();
void SetupCrt(); void SetupCrt();
using ExitFunc = void (*)();
void Atexit(ExitFunc exitFunc);
void Exit(int code);
} }

View File

@ -149,7 +149,7 @@ void DoRestart()
{ {
fprintf(stderr, "cannot restart: no executable name???\n"); fprintf(stderr, "cannot restart: no executable name???\n");
} }
exit(-1); Exit(-1);
} }
bool UpdateStart(const std::vector<char> &data) bool UpdateStart(const std::vector<char> &data)

View File

@ -209,14 +209,14 @@ void DoRestart()
} }
else else
{ {
exit(0); Exit(0);
} }
} }
else else
{ {
fprintf(stderr, "cannot restart: no executable name???\n"); fprintf(stderr, "cannot restart: no executable name???\n");
} }
exit(-1); Exit(-1);
} }
bool CanUpdate() bool CanUpdate()

View File

@ -212,6 +212,14 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
initHttpAPI(); initHttpAPI();
initSocketAPI(); initSocketAPI();
lua_getglobal(l, "os");
lua_pushcfunction(l, [](lua_State *l) -> int {
Platform::Exit(luaL_optinteger(l, 1, 0));
return 0;
});
lua_setfield(l, -2, "exit");
lua_pop(l, 1);
initBZ2API(l); initBZ2API(l);
//Old TPT API //Old TPT API