Skip to content

Commit

Permalink
engine: common: add Host_ExitInMain function that will force engine r…
Browse files Browse the repository at this point in the history
…eturn 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.
  • Loading branch information
a1batross committed Jan 9, 2025
1 parent 692bcc4 commit 90e493f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions engine/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions engine/common/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 )
{
Expand Down
10 changes: 10 additions & 0 deletions engine/common/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
}

/*
Expand Down

0 comments on commit 90e493f

Please sign in to comment.