Bp: clear DRs in onLastStrongRef
This way, if unlink is not called, the binder will properly
destruct. Currently linkToDeath takes a weakRef, and when
BR_DEAD_BINDER is received, userspace binder sends
BC_CLEAR_DEATH_NOTIFICATION for each death notification. Then, when it
receives BR_CLEAR_DEATH_NOTIFICATION_DONE (maybe later?), it clears the
weak ref. Right now, ~BpBinder also clears these. However, by moving
this clearing up to onLastStrongRef, forgotten unlinks will no longer
cause a cycle (that is only cleared when the service dies).
Bug: 134576445
Test: manually linking to death many times without unlinking.
Change-Id: Ib10550025caefa5dd674a5690c1165386cf89190
diff --git a/BpHwBinder.cpp b/BpHwBinder.cpp
index 9ae2e64..7c6e3ec 100644
--- a/BpHwBinder.cpp
+++ b/BpHwBinder.cpp
@@ -269,21 +269,6 @@
IPCThreadState* ipc = IPCThreadState::self();
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != nullptr) {
- if (ipc) ipc->clearDeathNotification(mHandle, this);
- mObituaries = nullptr;
- }
- mLock.unlock();
-
- if (obits != nullptr) {
- // XXX Should we tell any remaining DeathRecipient
- // objects that the last strong ref has gone away, so they
- // are no longer linked?
- delete obits;
- }
-
if (ipc) {
ipc->expungeHandle(mHandle, this);
ipc->decWeakHandle(mHandle);
@@ -308,6 +293,26 @@
ipc->decStrongHandle(mHandle);
ipc->flushCommands();
}
+
+ mLock.lock();
+ Vector<Obituary>* obits = mObituaries;
+ if(obits != nullptr) {
+ if (!obits->isEmpty()) {
+ ALOGI("onLastStrongRef automatically unlinking death recipients");
+ }
+
+ if (ipc) ipc->clearDeathNotification(mHandle, this);
+ mObituaries = nullptr;
+ }
+ mLock.unlock();
+
+ if (obits != nullptr) {
+ // XXX Should we tell any remaining DeathRecipient
+ // objects that the last strong ref has gone away, so they
+ // are no longer linked?
+ delete obits;
+ obits = nullptr;
+ }
}
bool BpHwBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)