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))
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);
}
}
@ -181,21 +181,9 @@ static std::unique_ptr<ExplicitSingletons> explicitSingletons;
int main(int argc, char * argv[])
{
Platform::SetupCrt();
atexit([]() {
ui::Engine::Ref().CloseWindow();
Platform::Atexit([]() {
SDLClose();
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>();
@ -318,7 +306,7 @@ int main(int argc, char * argv[])
FILE *new_stderr = freopen("stderr.log", "w", stderr);
if (!new_stdout || !new_stderr)
{
exit(42);
Platform::Exit(42);
}
}
@ -522,5 +510,6 @@ int main(int argc, char * argv[])
{
wrapWithBluescreen();
}
Platform::Exit(0);
return 0;
}

View File

@ -36,21 +36,9 @@ static std::unique_ptr<ExplicitSingletons> explicitSingletons;
int main(int argc, char * argv[])
{
Platform::SetupCrt();
atexit([]() {
ui::Engine::Ref().CloseWindow();
Platform::Atexit([]() {
SDLClose();
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>();
@ -99,9 +87,10 @@ int main(int argc, char * argv[])
else
{
std::cerr << "path to font.cpp not supplied" << std::endl;
exit(1);
Platform::Exit(1);
}
EngineProcess();
Platform::Exit(0);
return 0;
}

View File

@ -4,6 +4,7 @@
#include "Config.h"
#include "gui/interface/Engine.h"
#include "graphics/Graphics.h"
#include "common/Platform.h"
#include <iostream>
int desktopWidth = 1280;
@ -96,13 +97,13 @@ void SDLOpen()
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "Initializing SDL (video subsystem): %s\n", SDL_GetError());
exit(-1);
Platform::Exit(-1);
}
if (!RecreateWindow())
{
fprintf(stderr, "Creating SDL window: %s\n", SDL_GetError());
exit(-1);
Platform::Exit(-1);
}
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_)
{
// bool changingScale = scale != scale_;

View File

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

View File

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

View File

@ -3,6 +3,7 @@
#include "tpt-rand.h"
#include "Config.h"
#include <memory>
#include <list>
#include <cstring>
#include <fstream>
#include <iostream>
@ -106,4 +107,20 @@ bool WriteFile(const std::vector<char> &fileData, ByteString filename)
}
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 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");
}
exit(-1);
Exit(-1);
}
bool UpdateStart(const std::vector<char> &data)

View File

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

View File

@ -212,6 +212,14 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
initHttpAPI();
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);
//Old TPT API