Fixed bug 4579 - SDL_android.c s_active not being atomic

Isaias Brunet

This bug cause a false assert due to multiple threads modifying the same variable without any atomic operation.
This commit is contained in:
Sam Lantinga 2019-04-05 08:15:01 -07:00
parent 9eac91dd29
commit a46af76b07

View File

@ -1156,7 +1156,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
Functions called by SDL into Java Functions called by SDL into Java
*******************************************************************************/ *******************************************************************************/
static int s_active = 0; static SDL_atomic_t s_active;
struct LocalReferenceHolder struct LocalReferenceHolder
{ {
JNIEnv *m_env; JNIEnv *m_env;
@ -1181,7 +1181,7 @@ static SDL_bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder
SDL_SetError("Failed to allocate enough JVM local references"); SDL_SetError("Failed to allocate enough JVM local references");
return SDL_FALSE; return SDL_FALSE;
} }
++s_active; SDL_AtomicIncRef(&s_active);
refholder->m_env = env; refholder->m_env = env;
return SDL_TRUE; return SDL_TRUE;
} }
@ -1194,10 +1194,15 @@ static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder)
if (refholder->m_env) { if (refholder->m_env) {
JNIEnv *env = refholder->m_env; JNIEnv *env = refholder->m_env;
(*env)->PopLocalFrame(env, NULL); (*env)->PopLocalFrame(env, NULL);
--s_active; SDL_AtomicDecRef(&s_active);
} }
} }
static SDL_bool LocalReferenceHolder_IsActive(void)
{
return (SDL_AtomicGet(&s_active) > 0);
}
ANativeWindow* Android_JNI_GetNativeWindow(void) ANativeWindow* Android_JNI_GetNativeWindow(void)
{ {
ANativeWindow *anw = NULL; ANativeWindow *anw = NULL;
@ -1601,7 +1606,7 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
jthrowable exception; jthrowable exception;
/* Detect mismatch LocalReferenceHolder_Init/Cleanup */ /* Detect mismatch LocalReferenceHolder_Init/Cleanup */
SDL_assert((s_active > 0)); SDL_assert(LocalReferenceHolder_IsActive());
exception = (*env)->ExceptionOccurred(env); exception = (*env)->ExceptionOccurred(env);
if (exception != NULL) { if (exception != NULL) {