Description I’ve noticed that when this mod is installed with its default configuration, other SKSE plugins (including my own) fail to execute their standard shutdown logic. Specifically:
-
The WM_DESTROY message is never received by the window hook.
-
Standard DLL unloading procedures are bypassed.
-
Global destructors and RAII cleanup logic (e.g., static smart pointers) are not triggered.
Findings After investigating the configuration, I identified the cause as the bSafeExit setting. It appears this feature utilizes TerminateProcess to end the game. While this effectively prevents the "Infinite Loading on Exit" hang, it does so by killing the process abruptly, which prevents the OS from performing a clean teardown of the process threads and loaded modules.
The Impact on the Ecosystem Relying on WM_DESTROY or RAII for data persistence and resource management is a standard and reasonable practice in C++ development. By bypassing the shutdown cycle:
-
Data Loss: Plugins that save configuration or state data during the exit phase will lose all unsaved changes.
-
Resource Leaks: External handles or file locks may not be released properly.
-
Compatibility Issues: It forces other developers to overhaul their entire timing for cleanup just to accommodate this specific "fix."
Suggested Change I personally believe that using TerminateProcess by default is not a "safe" or sound design choice for a general-purpose utility.
Expected Behavior
-
The bSafeExit setting should be set to false by default.
-
This feature should be an "opt-in" for users who specifically suffer from exit hangs, rather than a global default that breaks standard plugin lifecycle expectations.
Description I’ve noticed that when this mod is installed with its default configuration, other SKSE plugins (including my own) fail to execute their standard shutdown logic. Specifically:
The
WM_DESTROYmessage is never received by the window hook.Standard DLL unloading procedures are bypassed.
Global destructors and RAII cleanup logic (e.g., static smart pointers) are not triggered.
Findings After investigating the configuration, I identified the cause as the
bSafeExitsetting. It appears this feature utilizesTerminateProcessto end the game. While this effectively prevents the "Infinite Loading on Exit" hang, it does so by killing the process abruptly, which prevents the OS from performing a clean teardown of the process threads and loaded modules.The Impact on the Ecosystem Relying on
WM_DESTROYor RAII for data persistence and resource management is a standard and reasonable practice in C++ development. By bypassing the shutdown cycle:Data Loss: Plugins that save configuration or state data during the exit phase will lose all unsaved changes.
Resource Leaks: External handles or file locks may not be released properly.
Compatibility Issues: It forces other developers to overhaul their entire timing for cleanup just to accommodate this specific "fix."
Suggested Change I personally believe that using
TerminateProcessby default is not a "safe" or sound design choice for a general-purpose utility.Expected Behavior
The
bSafeExitsetting should be set tofalseby default.This feature should be an "opt-in" for users who specifically suffer from exit hangs, rather than a global default that breaks standard plugin lifecycle expectations.