diff options
author | Dariusz Iwanoczko <dariusz.iwanoczko@sonymobile.com> | 2014-05-08 09:44:37 +0200 |
---|---|---|
committer | John Eckerdal <john.eckerdal@sonymobile.com> | 2014-11-11 13:12:53 +0100 |
commit | ed86e19af2e36397a1cd5b89105b1bf0de47414e (patch) | |
tree | 6b1b635e6537d472d20954ea9a2747ea3c47768b /media/jni | |
parent | 71f83672f297b116988defbe989869e5744cda5e (diff) | |
download | frameworks_base-ed86e19af2e36397a1cd5b89105b1bf0de47414e.zip frameworks_base-ed86e19af2e36397a1cd5b89105b1bf0de47414e.tar.gz frameworks_base-ed86e19af2e36397a1cd5b89105b1bf0de47414e.tar.bz2 |
Race-condition in SoundPool during release
There is race between SoundPoolThread and SoundPool / AudioManager
threads during releasing SoundPool.
AudioManager deletes a global reference before setting SoundPool
callback to NULL. If, at that time, a call to the SoundPool::notify
fuction happens then mCallback is valid but mUserData is not.
The following log will show up to indicate the problem:
JNI ERROR (app bug): accessed deleted global reference 0xXXXXXXXX
This fix is to clear the SoundPool's callback before releasing global
reference.
Change-Id: I5e6d647edc0444340db879428048e2c0a068a8b4
Diffstat (limited to 'media/jni')
-rw-r--r-- | media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp index ce20e52..baf61d5 100644 --- a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp +++ b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp @@ -231,14 +231,14 @@ android_media_SoundPool_SoundPoolImpl_release(JNIEnv *env, jobject thiz) SoundPool *ap = MusterSoundPool(env, thiz); if (ap != NULL) { - // release weak reference + // release weak reference and clear callback jobject weakRef = (jobject) ap->getUserData(); + ap->setCallback(NULL, NULL); if (weakRef != NULL) { env->DeleteGlobalRef(weakRef); } - // clear callback and native context - ap->setCallback(NULL, NULL); + // clear native context env->SetLongField(thiz, fields.mNativeContext, 0); delete ap; } |