diff options
| -rw-r--r-- | core/jni/android_util_Binder.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index fb8207553ece..634c9f754fc6 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -358,6 +358,8 @@ public: void add(const sp<JavaDeathRecipient>& recipient); void remove(const sp<JavaDeathRecipient>& recipient); sp<JavaDeathRecipient> find(jobject recipient); + + Mutex& lock(); // Use with care; specifically for mutual exclusion during binder death }; // ---------------------------------------------------------------------------- @@ -392,11 +394,18 @@ public: "*** Uncaught exception returned from death notification!"); } - // Demote from strong ref to weak after binderDied() has been delivered, - // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. - mObjectWeak = env->NewWeakGlobalRef(mObject); - env->DeleteGlobalRef(mObject); - mObject = NULL; + // Serialize with our containing DeathRecipientList so that we can't + // delete the global ref on mObject while the list is being iterated. + sp<DeathRecipientList> list = mList.promote(); + if (list != NULL) { + AutoMutex _l(list->lock()); + + // Demote from strong ref to weak after binderDied() has been delivered, + // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. + mObjectWeak = env->NewWeakGlobalRef(mObject); + env->DeleteGlobalRef(mObject); + mObject = NULL; + } } } @@ -518,6 +527,10 @@ sp<JavaDeathRecipient> DeathRecipientList::find(jobject recipient) { return NULL; } +Mutex& DeathRecipientList::lock() { + return mLock; +} + // ---------------------------------------------------------------------------- namespace android { |