mirror of
https://github.com/encounter/SDL.git
synced 2025-12-16 16:37:09 +00:00
Fixed bug 4142 - Concurrency issues in Android backend
Use a semaphore to prevent concurrency issues between Java Activity and Native thread code, when using 'Android_Window'. (Eg. Java sending Touch events, while native code is destroying the main SDL_Window. )
This commit is contained in:
@@ -39,8 +39,8 @@ static void ANDROIDAUDIO_ResumeDevices(void) {}
|
||||
static void ANDROIDAUDIO_PauseDevices(void) {}
|
||||
#endif
|
||||
|
||||
static void
|
||||
android_egl_context_restore(SDL_Window *window)
|
||||
static void
|
||||
android_egl_context_restore(SDL_Window *window)
|
||||
{
|
||||
SDL_Event event;
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
@@ -53,8 +53,8 @@ android_egl_context_restore(SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
android_egl_context_backup(SDL_Window *window)
|
||||
static void
|
||||
android_egl_context_backup(SDL_Window *window)
|
||||
{
|
||||
/* Keep a copy of the EGL Context so we can try to restore it when we resume */
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
@@ -80,7 +80,10 @@ Android_PumpEvents(_THIS)
|
||||
#if SDL_ANDROID_BLOCK_ON_PAUSE
|
||||
if (isPaused && !isPausing) {
|
||||
/* Make sure this is the last thing we do before pausing */
|
||||
SDL_SemWait(Android_ActivitySem);
|
||||
android_egl_context_backup(Android_Window);
|
||||
SDL_SemPost(Android_ActivitySem);
|
||||
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
if (SDL_SemWait(Android_ResumeSem) == 0) {
|
||||
#else
|
||||
@@ -91,7 +94,9 @@ Android_PumpEvents(_THIS)
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
if (!SDL_HasEvent(SDL_QUIT)) {
|
||||
SDL_SemWait(Android_ActivitySem);
|
||||
android_egl_context_restore(Android_Window);
|
||||
SDL_SemPost(Android_ActivitySem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +115,10 @@ Android_PumpEvents(_THIS)
|
||||
}
|
||||
#else
|
||||
if (SDL_SemTryWait(Android_PauseSem) == 0) {
|
||||
SDL_SemWait(Android_ActivitySem);
|
||||
android_egl_context_backup(Android_Window);
|
||||
SDL_SemPost(Android_ActivitySem);
|
||||
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
isPaused = 1;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ int Android_DeviceHeight = 0;
|
||||
static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN;
|
||||
static int Android_ScreenRate = 0;
|
||||
|
||||
SDL_sem *Android_PauseSem = NULL, *Android_ResumeSem = NULL;
|
||||
SDL_sem *Android_PauseSem = NULL, *Android_ResumeSem = NULL, *Android_ActivitySem = NULL;
|
||||
|
||||
static int
|
||||
Android_Available(void)
|
||||
|
||||
@@ -41,7 +41,7 @@ extern int Android_SurfaceWidth;
|
||||
extern int Android_SurfaceHeight;
|
||||
extern int Android_DeviceWidth;
|
||||
extern int Android_DeviceHeight;
|
||||
extern SDL_sem *Android_PauseSem, *Android_ResumeSem;
|
||||
extern SDL_sem *Android_PauseSem, *Android_ResumeSem, *Android_ActivitySem;
|
||||
|
||||
#endif /* SDL_androidvideo_h_ */
|
||||
|
||||
|
||||
@@ -41,12 +41,14 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *data;
|
||||
int retval = 0;
|
||||
|
||||
|
||||
SDL_SemWait(Android_ActivitySem);
|
||||
|
||||
if (Android_Window) {
|
||||
retval = SDL_SetError("Android only supports one window");
|
||||
goto endfunction;
|
||||
}
|
||||
|
||||
|
||||
Android_PauseSem = SDL_CreateSemaphore(0);
|
||||
Android_ResumeSem = SDL_CreateSemaphore(0);
|
||||
|
||||
@@ -67,15 +69,15 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
||||
/* One window, it always has focus */
|
||||
SDL_SetMouseFocus(window);
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
|
||||
data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
retval = SDL_OutOfMemory();
|
||||
goto endfunction;
|
||||
}
|
||||
|
||||
|
||||
data->native_window = Android_JNI_GetNativeWindow();
|
||||
|
||||
|
||||
if (!data->native_window) {
|
||||
SDL_free(data);
|
||||
retval = SDL_SetError("Could not fetch native window");
|
||||
@@ -99,7 +101,9 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
||||
Android_Window = window;
|
||||
|
||||
endfunction:
|
||||
|
||||
|
||||
SDL_SemPost(Android_ActivitySem);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -146,14 +150,16 @@ Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display
|
||||
|
||||
void
|
||||
Android_DestroyWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
{
|
||||
SDL_SemWait(Android_ActivitySem);
|
||||
|
||||
if (window == Android_Window) {
|
||||
Android_Window = NULL;
|
||||
if (Android_PauseSem) SDL_DestroySemaphore(Android_PauseSem);
|
||||
if (Android_ResumeSem) SDL_DestroySemaphore(Android_ResumeSem);
|
||||
Android_PauseSem = NULL;
|
||||
Android_ResumeSem = NULL;
|
||||
|
||||
|
||||
if (window->driverdata) {
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
@@ -166,6 +172,8 @@ Android_DestroyWindow(_THIS, SDL_Window *window)
|
||||
window->driverdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SemPost(Android_ActivitySem);
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
|
||||
Reference in New Issue
Block a user