Android: concurrency issues, make sure Activity is in running State when calling
authorSylvain Becker <sylvain.becker@gmail.com>
Fri, 28 Jun 2019 16:38:42 +0200
changeset 12910dd9169424181
parent 12909 8e27bc5f03d8
child 12911 0c19a7239a95
Android: concurrency issues, make sure Activity is in running State when calling
functions like SDL_CreateWindow, SDL_CreateRenderer, Android_GLES_CreateContext

Bugs 4694, 4681, 4142
src/core/android/SDL_android.c
src/core/android/SDL_android.h
src/render/SDL_render.c
src/video/android/SDL_androidgl.c
src/video/android/SDL_androidwindow.c
     1.1 --- a/src/core/android/SDL_android.c	Fri Jun 28 16:14:50 2019 +0200
     1.2 +++ b/src/core/android/SDL_android.c	Fri Jun 28 16:38:42 2019 +0200
     1.3 @@ -24,6 +24,7 @@
     1.4  #include "SDL_hints.h"
     1.5  #include "SDL_log.h"
     1.6  #include "SDL_main.h"
     1.7 +#include "SDL_timer.h"
     1.8  
     1.9  #ifdef __ANDROID__
    1.10  
    1.11 @@ -720,6 +721,25 @@
    1.12      SDL_UnlockMutex(Android_ActivityMutex);
    1.13  }
    1.14  
    1.15 +/* Lock the Mutex when the Activity is in its 'Running' state */
    1.16 +void Android_ActivityMutex_Lock_Running() {
    1.17 +    int pauseSignaled = 0;
    1.18 +    int resumeSignaled = 0;
    1.19 +
    1.20 +retry:
    1.21 +
    1.22 +    SDL_LockMutex(Android_ActivityMutex);
    1.23 +
    1.24 +    pauseSignaled = SDL_SemValue(Android_PauseSem);
    1.25 +    resumeSignaled = SDL_SemValue(Android_ResumeSem);
    1.26 +
    1.27 +    if (pauseSignaled > resumeSignaled) {
    1.28 +        SDL_UnlockMutex(Android_ActivityMutex);
    1.29 +        SDL_Delay(50);
    1.30 +        goto retry;
    1.31 +    }
    1.32 +}
    1.33 +
    1.34  /* Set screen resolution */
    1.35  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
    1.36                                      JNIEnv *env, jclass jcls,
     2.1 --- a/src/core/android/SDL_android.h	Fri Jun 28 16:14:50 2019 +0200
     2.2 +++ b/src/core/android/SDL_android.h	Fri Jun 28 16:38:42 2019 +0200
     2.3 @@ -133,6 +133,7 @@
     2.4  
     2.5  void Android_ActivityMutex_Lock(void);
     2.6  void Android_ActivityMutex_Unlock(void);
     2.7 +void Android_ActivityMutex_Lock_Running(void);
     2.8  
     2.9  /* Ends C function definitions when using C++ */
    2.10  #ifdef __cplusplus
     3.1 --- a/src/render/SDL_render.c	Fri Jun 28 16:14:50 2019 +0200
     3.2 +++ b/src/render/SDL_render.c	Fri Jun 28 16:38:42 2019 +0200
     3.3 @@ -29,6 +29,9 @@
     3.4  #include "SDL_sysrender.h"
     3.5  #include "software/SDL_render_sw_c.h"
     3.6  
     3.7 +#if defined(__ANDROID__)
     3.8 +#  include "../core/android/SDL_android.h"
     3.9 +#endif
    3.10  
    3.11  #define SDL_WINDOWRENDERDATA    "_SDL_WindowRenderData"
    3.12  
    3.13 @@ -837,6 +840,10 @@
    3.14      SDL_bool batching = SDL_TRUE;
    3.15      const char *hint;
    3.16  
    3.17 +#if defined(__ANDROID__)
    3.18 +    Android_ActivityMutex_Lock_Running();
    3.19 +#endif
    3.20 +
    3.21      if (!window) {
    3.22          SDL_SetError("Invalid window");
    3.23          goto error;
    3.24 @@ -951,9 +958,16 @@
    3.25      SDL_LogInfo(SDL_LOG_CATEGORY_RENDER,
    3.26                  "Created renderer: %s", renderer->info.name);
    3.27  
    3.28 +#if defined(__ANDROID__)
    3.29 +    Android_ActivityMutex_Unlock();
    3.30 +#endif
    3.31      return renderer;
    3.32  
    3.33  error:
    3.34 +
    3.35 +#if defined(__ANDROID__)
    3.36 +    Android_ActivityMutex_Unlock();
    3.37 +#endif
    3.38      return NULL;
    3.39  
    3.40  #else
     4.1 --- a/src/video/android/SDL_androidgl.c	Fri Jun 28 16:14:50 2019 +0200
     4.2 +++ b/src/video/android/SDL_androidgl.c	Fri Jun 28 16:38:42 2019 +0200
     4.3 @@ -49,7 +49,15 @@
     4.4  SDL_GLContext
     4.5  Android_GLES_CreateContext(_THIS, SDL_Window * window)
     4.6  {
     4.7 -    return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
     4.8 +    SDL_GLContext ret;
     4.9 +
    4.10 +    Android_ActivityMutex_Lock_Running();
    4.11 +
    4.12 +    ret = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
    4.13 +
    4.14 +    SDL_UnlockMutex(Android_ActivityMutex);
    4.15 +
    4.16 +    return ret;
    4.17  }
    4.18  
    4.19  int
     5.1 --- a/src/video/android/SDL_androidwindow.c	Fri Jun 28 16:14:50 2019 +0200
     5.2 +++ b/src/video/android/SDL_androidwindow.c	Fri Jun 28 16:38:42 2019 +0200
     5.3 @@ -42,7 +42,7 @@
     5.4      SDL_WindowData *data;
     5.5      int retval = 0;
     5.6  
     5.7 -    SDL_LockMutex(Android_ActivityMutex);
     5.8 +    Android_ActivityMutex_Lock_Running();
     5.9  
    5.10      if (Android_Window) {
    5.11          retval = SDL_SetError("Android only supports one window");