am 54bb9869: Merge "Don\'t fail unlinking death recipients on dead binders" into honeycomb-mr1

* commit '54bb98698a3550250b332b2f4d756b1a5c7473f5':
  Don't fail unlinking death recipients on dead binders
This commit is contained in:
Mike Cleron
2011-03-04 18:00:29 -08:00
committed by Android Git Automerger

View File

@@ -44,6 +44,13 @@
//#undef LOGV //#undef LOGV
//#define LOGV(...) fprintf(stderr, __VA_ARGS__) //#define LOGV(...) fprintf(stderr, __VA_ARGS__)
#define DEBUG_DEATH 0
#if DEBUG_DEATH
#define LOGDEATH LOGD
#else
#define LOGDEATH LOGV
#endif
using namespace android; using namespace android;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -363,6 +370,7 @@ class DeathRecipientList : public RefBase {
Mutex mLock; Mutex mLock;
public: public:
DeathRecipientList();
~DeathRecipientList(); ~DeathRecipientList();
void add(const sp<JavaDeathRecipient>& recipient); void add(const sp<JavaDeathRecipient>& recipient);
@@ -380,6 +388,7 @@ public:
{ {
// These objects manage their own lifetimes so are responsible for final bookkeeping. // These objects manage their own lifetimes so are responsible for final bookkeeping.
// The list holds a strong reference to this object. // The list holds a strong reference to this object.
LOGDEATH("Adding JDR %p to DRL %p", this, list.get());
list->add(this); list->add(this);
android_atomic_inc(&gNumDeathRefs); android_atomic_inc(&gNumDeathRefs);
@@ -390,7 +399,7 @@ public:
{ {
JNIEnv* env = javavm_to_jnienv(mVM); JNIEnv* env = javavm_to_jnienv(mVM);
LOGV("Receiving binderDied() on JavaDeathRecipient %p\n", this); LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
env->CallStaticVoidMethod(gBinderProxyOffsets.mClass, env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mSendDeathNotice, mObject); gBinderProxyOffsets.mSendDeathNotice, mObject);
@@ -399,15 +408,16 @@ public:
report_exception(env, excep, report_exception(env, excep,
"*** Uncaught exception returned from death notification!"); "*** Uncaught exception returned from death notification!");
} }
clearReference();
} }
void clearReference() void clearReference()
{ {
sp<DeathRecipientList> list = mList.promote(); sp<DeathRecipientList> list = mList.promote();
if (list != NULL) { if (list != NULL) {
LOGDEATH("Removing JDR %p from DRL %p", this, list.get());
list->remove(this); list->remove(this);
} else {
LOGDEATH("clearReference() on JDR %p but DRL wp purged", this);
} }
} }
@@ -433,7 +443,12 @@ private:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
DeathRecipientList::DeathRecipientList() {
LOGDEATH("New DRL @ %p", this);
}
DeathRecipientList::~DeathRecipientList() { DeathRecipientList::~DeathRecipientList() {
LOGDEATH("Destroy DRL @ %p", this);
AutoMutex _l(mLock); AutoMutex _l(mLock);
// Should never happen -- the JavaDeathRecipient objects that have added themselves // Should never happen -- the JavaDeathRecipient objects that have added themselves
@@ -447,6 +462,7 @@ DeathRecipientList::~DeathRecipientList() {
void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) { void DeathRecipientList::add(const sp<JavaDeathRecipient>& recipient) {
AutoMutex _l(mLock); AutoMutex _l(mLock);
LOGDEATH("DRL @ %p : add JDR %p", this, recipient.get());
mList.push_back(recipient); mList.push_back(recipient);
} }
@@ -456,6 +472,7 @@ void DeathRecipientList::remove(const sp<JavaDeathRecipient>& recipient) {
List< sp<JavaDeathRecipient> >::iterator iter; List< sp<JavaDeathRecipient> >::iterator iter;
for (iter = mList.begin(); iter != mList.end(); iter++) { for (iter = mList.begin(); iter != mList.end(); iter++) {
if (*iter == recipient) { if (*iter == recipient) {
LOGDEATH("DRL @ %p : remove JDR %p", this, recipient.get());
mList.erase(iter); mList.erase(iter);
return; return;
} }
@@ -518,7 +535,7 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) { if (object != NULL) {
LOGV("objectForBinder %p: created new proxy %p !\n", val.get(), object); LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object. // The proxy holds a reference to the native object.
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
val->incStrong(object); val->incStrong(object);
@@ -1030,7 +1047,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
assert(false); assert(false);
} }
LOGV("linkToDeath: binder=%p recipient=%p\n", target, recipient); LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) { if (!target->localBinder()) {
DeathRecipientList* list = (DeathRecipientList*) DeathRecipientList* list = (DeathRecipientList*)
@@ -1062,7 +1079,7 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
return JNI_FALSE; return JNI_FALSE;
} }
LOGV("unlinkToDeath: binder=%p recipient=%p\n", target, recipient); LOGDEATH("unlinkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) { if (!target->localBinder()) {
status_t err = NAME_NOT_FOUND; status_t err = NAME_NOT_FOUND;
@@ -1071,6 +1088,7 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj,
DeathRecipientList* list = (DeathRecipientList*) DeathRecipientList* list = (DeathRecipientList*)
env->GetIntField(obj, gBinderProxyOffsets.mOrgue); env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
sp<JavaDeathRecipient> origJDR = list->find(recipient); sp<JavaDeathRecipient> origJDR = list->find(recipient);
LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get());
if (origJDR != NULL) { if (origJDR != NULL) {
wp<IBinder::DeathRecipient> dr; wp<IBinder::DeathRecipient> dr;
err = target->unlinkToDeath(origJDR, NULL, flags, &dr); err = target->unlinkToDeath(origJDR, NULL, flags, &dr);
@@ -1101,7 +1119,7 @@ static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
DeathRecipientList* drl = (DeathRecipientList*) DeathRecipientList* drl = (DeathRecipientList*)
env->GetIntField(obj, gBinderProxyOffsets.mOrgue); env->GetIntField(obj, gBinderProxyOffsets.mOrgue);
LOGV("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl); LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
env->SetIntField(obj, gBinderProxyOffsets.mObject, 0); env->SetIntField(obj, gBinderProxyOffsets.mObject, 0);
env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0); env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0);
drl->decStrong((void*)javaObjectForIBinder); drl->decStrong((void*)javaObjectForIBinder);