system: flush logs and _Exit on quit for macOS and Linux instead of tearing down under live guest threads
This commit is contained in:
parent
f3089c790f
commit
705b78f53e
4 changed files with 33 additions and 7 deletions
|
|
@ -71,6 +71,13 @@ void InitLoggingEarly();
|
||||||
*/
|
*/
|
||||||
void ShutdownLogging();
|
void ShutdownLogging();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush all loggers without shutting the logging system down. Safe to call
|
||||||
|
* while other threads may still be logging; intended for fast-exit paths
|
||||||
|
* that end the process with _Exit right after flushing.
|
||||||
|
*/
|
||||||
|
void FlushLogging();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new log category at runtime.
|
* Register a new log category at runtime.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,16 @@ void InitLogging(const char* log_file, spdlog::level::level_enum level) {
|
||||||
InitLogging(config);
|
InitLogging(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlushLogging() {
|
||||||
|
std::lock_guard lock(g_mutex);
|
||||||
|
if (!g_initialized && !g_early_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& entry : g_registry)
|
||||||
|
if (entry.logger)
|
||||||
|
entry.logger->flush();
|
||||||
|
}
|
||||||
|
|
||||||
void ShutdownLogging() {
|
void ShutdownLogging() {
|
||||||
std::lock_guard lock(g_mutex);
|
std::lock_guard lock(g_mutex);
|
||||||
if (!g_initialized && !g_early_initialized)
|
if (!g_initialized && !g_early_initialized)
|
||||||
|
|
|
||||||
|
|
@ -75,5 +75,8 @@ extern "C" int main(int argc_pre_gtk, char** argv_pre_gtk) {
|
||||||
// Logging may still be needed in the destructors.
|
// Logging may still be needed in the destructors.
|
||||||
rex::ShutdownLogging();
|
rex::ShutdownLogging();
|
||||||
|
|
||||||
return result;
|
// Guest threads that could not be cancelled may still be running; global
|
||||||
|
// static destruction under them can turn a clean quit into an abort or a
|
||||||
|
// nonzero exit status. Everything is flushed - end the process here.
|
||||||
|
std::_Exit(result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,22 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
bool initialized = app->OnInitialize();
|
bool initialized = app->OnInitialize();
|
||||||
result = initialized ? app_context.RunMainLoop() : EXIT_FAILURE;
|
result = initialized ? app_context.RunMainLoop() : EXIT_FAILURE;
|
||||||
|
#if REX_PLATFORM_MAC
|
||||||
|
// Skip app/runtime teardown entirely: guest threads cannot be reliably
|
||||||
|
// stopped on Darwin (pthread_cancel only lands at cancellation points,
|
||||||
|
// never in CPU-bound recompiled code), so the destructor chain races
|
||||||
|
// still-running guest threads over freed kernel objects and turns a
|
||||||
|
// normal quit into the macOS crash-reporter dialog. Flush the logs and
|
||||||
|
// leave; the OS reclaims everything else. Flush-only on purpose -
|
||||||
|
// ShutdownLogging destroys sinks a straggler thread may still be using.
|
||||||
|
rex::FlushLogging();
|
||||||
|
std::_Exit(result);
|
||||||
|
#else
|
||||||
app->InvokeOnDestroy();
|
app->InvokeOnDestroy();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
rex::ShutdownLogging();
|
rex::ShutdownLogging();
|
||||||
#if REX_PLATFORM_MAC
|
|
||||||
// After explicit app teardown and log flushing, avoid macOS/SDL/global static
|
|
||||||
// teardown paths that can change a clean Close Game exit into status 1.
|
|
||||||
std::_Exit(result);
|
|
||||||
#else
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue