engine: common: add Host_ExitInMain function that will force engine return from Host_Main() function, essentially making engine gracefully exit on Android

In future, this might be used everywhere, so users would be able to add custom
cleanup in some advanced game_launch implementation, on any platform.
This commit is contained in:
Alibek Omarov 2025-01-09 20:26:14 +03:00
parent 692bcc4073
commit 90e493fa3a
3 changed files with 37 additions and 0 deletions

View file

@ -559,6 +559,7 @@ void Host_Error( const char *error, ... ) FORMAT_CHECK( 1 );
void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features );
void Host_Frame( double time );
void Host_Credits( void );
void Host_ExitInMain( void );
//
// host_state.c

View file

@ -43,6 +43,27 @@ GNU General Public License for more details.
static pfnChangeGame pChangeGame = NULL;
host_parm_t host; // host parms
#if XASH_ANDROID
static jmp_buf return_from_main_buf;
/*
===============
Host_ExitInMain
On some platforms (e.g. Android) we can't exit with exit(3) as calling it would
kill wrapper process (e.g. app_process) too early, before all resources would
be freed, contexts released, files closed, etc, etc...
To fix this, we create jmp_buf in Host_Main function, when jumping into with
non-zero value will immediately return from it with `error_on_exit`.
===============
*/
void Host_ExitInMain( void )
{
longjmp( return_from_main_buf, 1 );
}
#endif // XASH_ANDROID
#ifdef XASH_ENGINE_TESTS
struct tests_stats_s tests_stats;
#endif
@ -1319,6 +1340,11 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
// check after all configs were executed
HPAK_CheckIntegrity( hpk_custom_file.string );
#if XASH_ANDROID
if( setjmp( return_from_main_buf ))
return error_on_exit;
#endif // XASH_ANDROID
// main window message loop
while( !host.crashed )
{

View file

@ -420,6 +420,12 @@ void Sys_Error( const char *error, ... )
_exit->_Exit->asm._exit->_exit
As we do not need atexit(), just throw hidden exception
*/
// Hey, you, making an Emscripten port!
// What if we're not supposed to use exit() on Emscripten and instead we should
// exit from the main() function? Would this fix this bug? Test this case, pls.
#error "Read the comment above"
#include <emscripten.h>
#define exit my_exit
void my_exit(int ret)
@ -438,7 +444,11 @@ Sys_Quit
void Sys_Quit( const char *reason )
{
Host_ShutdownWithReason( reason );
#if XASH_ANDROID
Host_ExitInMain();
#else
exit( error_on_exit );
#endif
}
/*