libbinder_ndk: unlinkToDeath dead proxy
This CL automatically unlinks to death when a proxy dies (to clean
up additional data) and documents the behavior.
Bug: N/A
Test: ./runtests.sh
Change-Id: Ib092b25273a51f5afb12904bfe491927ad404f8d
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index 202d6d2..5cb68c2 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -128,13 +128,14 @@
//
// When the AIBinder_DeathRecipient is dropped, so are the actual underlying death recipients. When
// the IBinder dies, only a wp to it is kept.
-struct AIBinder_DeathRecipient {
+struct AIBinder_DeathRecipient : ::android::RefBase {
// One of these is created for every linkToDeath. This is to be able to recover data when a
// binderDied receipt only gives us information about the IBinder.
struct TransferDeathRecipient : ::android::IBinder::DeathRecipient {
TransferDeathRecipient(const ::android::wp<::android::IBinder>& who, void* cookie,
+ const ::android::wp<AIBinder_DeathRecipient>& parentRecipient,
const AIBinder_DeathRecipient_onBinderDied onDied)
- : mWho(who), mCookie(cookie), mOnDied(onDied) {}
+ : mWho(who), mCookie(cookie), mParentRecipient(parentRecipient), mOnDied(onDied) {}
void binderDied(const ::android::wp<::android::IBinder>& who) override;
@@ -144,14 +145,24 @@
private:
::android::wp<::android::IBinder> mWho;
void* mCookie;
+
+ ::android::wp<AIBinder_DeathRecipient> mParentRecipient;
+
+ // This is kept separately from AIBinder_DeathRecipient in case the death recipient is
+ // deleted while the death notification is fired
const AIBinder_DeathRecipient_onBinderDied mOnDied;
};
explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
- binder_status_t linkToDeath(AIBinder* binder, void* cookie);
- binder_status_t unlinkToDeath(AIBinder* binder, void* cookie);
+ binder_status_t linkToDeath(::android::sp<::android::IBinder>, void* cookie);
+ binder_status_t unlinkToDeath(::android::sp<::android::IBinder> binder, void* cookie);
private:
+ // When the user of this API deletes a Bp object but not the death recipient, the
+ // TransferDeathRecipient object can't be cleaned up. This is called whenever a new
+ // TransferDeathRecipient is linked, and it ensures that mDeathRecipients can't grow unbounded.
+ void pruneDeadTransferEntriesLocked();
+
std::mutex mDeathRecipientsMutex;
std::vector<::android::sp<TransferDeathRecipient>> mDeathRecipients;
AIBinder_DeathRecipient_onBinderDied mOnDied;