mirror of https://github.com/encounter/SDL.git
dynapi: Deal with failure cases better, other fixes.
Fixes Bugzilla #4803.
This commit is contained in:
parent
fe20c35be8
commit
ec04110d8e
27
src/SDL.c
27
src/SDL.c
|
@ -45,6 +45,33 @@ extern int SDL_HelperWindowDestroy(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* This is not declared in any header, although it is shared between some
|
||||||
|
parts of SDL, because we don't want anything calling it without an
|
||||||
|
extremely good reason. */
|
||||||
|
SDL_NORETURN void SDL_ExitProcess(const int exitcode)
|
||||||
|
{
|
||||||
|
#ifdef __WIN32__
|
||||||
|
/* "if you do not know the state of all threads in your process, it is
|
||||||
|
better to call TerminateProcess than ExitProcess"
|
||||||
|
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
|
||||||
|
TerminateProcess(GetCurrentProcess(), exitcode);
|
||||||
|
/* MingW doesn't have TerminateProcess marked as noreturn, so add an
|
||||||
|
ExitProcess here that will never be reached but make MingW happy. */
|
||||||
|
ExitProcess(exitcode);
|
||||||
|
#elif defined(__EMSCRIPTEN__)
|
||||||
|
emscripten_cancel_main_loop(); /* this should "kill" the app. */
|
||||||
|
emscripten_force_exit(exitcode); /* this should "kill" the app. */
|
||||||
|
exit(exitcode);
|
||||||
|
#elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
|
||||||
|
_exit(exitcode);
|
||||||
|
#elif defined(HAVE__EXIT) /* Upper case _Exit() */
|
||||||
|
_Exit(exitcode);
|
||||||
|
#else
|
||||||
|
_exit(exitcode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The initialized subsystems */
|
/* The initialized subsystems */
|
||||||
#ifdef SDL_MAIN_NEEDED
|
#ifdef SDL_MAIN_NEEDED
|
||||||
static SDL_bool SDL_MainIsReady = SDL_FALSE;
|
static SDL_bool SDL_MainIsReady = SDL_FALSE;
|
||||||
|
|
|
@ -120,32 +120,14 @@ static void SDL_GenerateAssertionReport(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is not declared in any header, although it is shared between some
|
||||||
|
parts of SDL, because we don't want anything calling it without an
|
||||||
|
extremely good reason. */
|
||||||
#if defined(__WATCOMC__)
|
#if defined(__WATCOMC__)
|
||||||
static void SDL_ExitProcess (int);
|
void SDL_ExitProcess(const int exitcode);
|
||||||
#pragma aux SDL_ExitProcess aborts;
|
#pragma aux SDL_ExitProcess aborts;
|
||||||
#endif
|
#endif
|
||||||
static SDL_NORETURN void SDL_ExitProcess(int exitcode)
|
SDL_NORETURN void SDL_ExitProcess(const int exitcode);
|
||||||
{
|
|
||||||
#ifdef __WIN32__
|
|
||||||
/* "if you do not know the state of all threads in your process, it is
|
|
||||||
better to call TerminateProcess than ExitProcess"
|
|
||||||
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
|
|
||||||
TerminateProcess(GetCurrentProcess(), exitcode);
|
|
||||||
/* MingW doesn't have TerminateProcess marked as noreturn, so add an
|
|
||||||
ExitProcess here that will never be reached but make MingW happy. */
|
|
||||||
ExitProcess(exitcode);
|
|
||||||
#elif defined(__EMSCRIPTEN__)
|
|
||||||
emscripten_cancel_main_loop(); /* this should "kill" the app. */
|
|
||||||
emscripten_force_exit(exitcode); /* this should "kill" the app. */
|
|
||||||
exit(exitcode);
|
|
||||||
#elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
|
|
||||||
_exit(exitcode);
|
|
||||||
#elif defined(HAVE__EXIT) /* Upper case _Exit() */
|
|
||||||
_Exit(exitcode);
|
|
||||||
#else
|
|
||||||
_exit(exitcode);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__WATCOMC__)
|
#if defined(__WATCOMC__)
|
||||||
|
|
|
@ -264,30 +264,59 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void dynapi_warn(const char *msg)
|
||||||
|
{
|
||||||
|
const char *caption = "SDL Dynamic API Failure!";
|
||||||
|
/* SDL_ShowSimpleMessageBox() is a too heavy for here. */
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg);
|
||||||
|
fflush(stderr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is not declared in any header, although it is shared between some
|
||||||
|
parts of SDL, because we don't want anything calling it without an
|
||||||
|
extremely good reason. */
|
||||||
|
#if defined(__WATCOMC__)
|
||||||
|
void SDL_ExitProcess(const int exitcode);
|
||||||
|
#pragma aux SDL_ExitProcess aborts;
|
||||||
|
#endif
|
||||||
|
SDL_NORETURN void SDL_ExitProcess(const int exitcode);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SDL_InitDynamicAPILocked(void)
|
SDL_InitDynamicAPILocked(void)
|
||||||
{
|
{
|
||||||
const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API");
|
const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API");
|
||||||
SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
|
SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
|
||||||
|
SDL_bool use_internal = SDL_TRUE;
|
||||||
|
|
||||||
if (libname) {
|
if (libname) {
|
||||||
entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry");
|
entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry");
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
/* !!! FIXME: fail to startup here instead? */
|
dynapi_warn("Couldn't load overriding SDL library. Please fix or remove the SDL_DYNAMIC_API environment variable. Using the default SDL.");
|
||||||
/* !!! FIXME: definitely warn user. */
|
/* Just fill in the function pointers from this library, later. */
|
||||||
/* Just fill in the function pointers from this library. */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry || (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0)) {
|
if (entry) {
|
||||||
/* !!! FIXME: fail to startup here instead? */
|
if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) {
|
||||||
/* !!! FIXME: definitely warn user. */
|
dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the SDL_DYNAMIC_API environment variable. Using the default SDL.");
|
||||||
/* Just fill in the function pointers from this library. */
|
/* Just fill in the function pointers from this library, later. */
|
||||||
if (!entry) {
|
} else {
|
||||||
if (!initialize_jumptable(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table))) {
|
use_internal = SDL_FALSE; /* We overrode SDL! Don't use the internal version! */
|
||||||
/* !!! FIXME: now we're screwed. Should definitely abort now. */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Just fill in the function pointers from this library. */
|
||||||
|
if (use_internal) {
|
||||||
|
if (initialize_jumptable(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) {
|
||||||
|
/* Now we're screwed. Should definitely abort now. */
|
||||||
|
dynapi_warn("Failed to initialize internal SDL dynapi. As this would otherwise crash, we have to abort now.");
|
||||||
|
SDL_ExitProcess(86);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we intentionally never close the newly-loaded lib, of course. */
|
/* we intentionally never close the newly-loaded lib, of course. */
|
||||||
|
|
Loading…
Reference in New Issue