summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2017-07-05 12:21:00 +0200
committerMartijn Coenen <maco@google.com>2017-07-06 11:02:28 +0200
commit32c8bdc9fdbcac0302c5c1131b9d7cd0c1b9fafe (patch)
treee84ba7f14d338075da9b21ce57d88c94b0cb0b41
parentf9e1f592c334c4b82ed18b73f507d9466a197801 (diff)
downloadlibhidl-32c8bdc9fdbcac0302c5c1131b9d7cd0c1b9fafe.tar.gz
Fix proxy memory leak.
Proxy objects that had a death recipient registered could not be freed; this is because of the following chain of events: - Proxy objects extend BpHwRefBase - BpHwRefBase extends the lifetime of the object to weak - meaning it will only get freed when both all strong *and* weak references are gone. - When a death recipient is registered, it keeps a weak reference to the proxy object (it needs to, so it can pass the object in the callback). - The death recipient objects are kept in a vector of sp<> objects. - Now, whenever the last strong reference to the proxy goes away in client code, the proxy object destructor will not run, because of the weak reference left in the death recipient. - But, the death recipient won't get destructed either, because it would only get destructed in the proxy destructor. This fixes the leak only in case the death recipient fires; in case the last strong reference to the proxy object is removed by the client without the death recipient having fired, the leak remains. This can be prevented in client code by calling unlinkToDeath() before getting rid of a proxy object. Bug:62319810 (?) Bug:63127792 Test: mma, hidl_test Change-Id: I686863ab462e63d98737cfc5ae50a6a8fa0081c0 Merged-In: I686863ab462e63d98737cfc5ae50a6a8fa0081c0
-rw-r--r--transport/HidlBinderSupport.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index d293542..fe1ccbc 100644
--- a/transport/HidlBinderSupport.cpp
+++ b/transport/HidlBinderSupport.cpp
@@ -35,9 +35,10 @@ hidl_binder_death_recipient::hidl_binder_death_recipient(const sp<hidl_death_rec
void hidl_binder_death_recipient::binderDied(const wp<IBinder>& /*who*/) {
sp<hidl_death_recipient> recipient = mRecipient.promote();
- if (recipient != nullptr) {
+ if (recipient != nullptr && mBase != nullptr) {
recipient->serviceDied(mCookie, mBase);
}
+ mBase = nullptr;
}
wp<hidl_death_recipient> hidl_binder_death_recipient::getRecipient() {