summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2021-06-25 21:30:23 +0000
committer Steven Moreland <smoreland@google.com> 2021-06-25 22:41:02 +0000
commit9e759e81a53bd0f5027f3a0a37661206d46774a3 (patch)
tree21e3d712b38971baef5f86ca603ad3e8161d2a59
parent2505ec424c80132755372cb0e8cb4e65f8d9fae1 (diff)
libbinder: add IBinder::withLock
BpBinder (and BBinder, once its mExtra allocation is made) have very nice and shiny locks which they keep all for themselves! Stop it, IBinder! Share that lock! This provides convenient access to IBinder's lock, in order to avoid needing additional locks elsewhere. Bug: 192023359 Test: N/A Change-Id: Id3485a2ac66d19379dcad2f0b41d6cb7a8a96725
-rw-r--r--libs/binder/Binder.cpp19
-rw-r--r--libs/binder/BpBinder.cpp5
-rw-r--r--libs/binder/include/binder/Binder.h1
-rw-r--r--libs/binder/include/binder/BpBinder.h1
-rw-r--r--libs/binder/include/binder/IBinder.h10
5 files changed, 36 insertions, 0 deletions
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 49653867b1..53750c940b 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -179,6 +179,17 @@ status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd,
return transact(SET_RPC_CLIENT_TRANSACTION, data, &reply);
}
+void IBinder::withLock(const std::function<void()>& doWithLock) {
+ BBinder* local = localBinder();
+ if (local) {
+ local->withLock(doWithLock);
+ return;
+ }
+ BpBinder* proxy = this->remoteBinder();
+ LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
+ proxy->withLock(doWithLock);
+}
+
// ---------------------------------------------------------------------------
class BBinder::RpcServerLink : public IBinder::DeathRecipient {
@@ -337,6 +348,14 @@ void* BBinder::detachObject(const void* objectID) {
return e->mObjects.detach(objectID);
}
+void BBinder::withLock(const std::function<void()>& doWithLock) {
+ Extras* e = getOrCreateExtras();
+ LOG_ALWAYS_FATAL_IF(!e, "no memory");
+
+ AutoMutex _l(e->mLock);
+ doWithLock();
+}
+
BBinder* BBinder::localBinder()
{
return this;
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 1f67825efc..3099296219 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -427,6 +427,11 @@ void* BpBinder::detachObject(const void* objectID) {
return mObjects.detach(objectID);
}
+void BpBinder::withLock(const std::function<void()>& doWithLock) {
+ AutoMutex _l(mLock);
+ doWithLock();
+}
+
BpBinder* BpBinder::remoteBinder()
{
return this;
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index b2fa2506c4..46223bb00e 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -58,6 +58,7 @@ public:
object_cleanup_func func) final;
virtual void* findObject(const void* objectID) const final;
virtual void* detachObject(const void* objectID) final;
+ void withLock(const std::function<void()>& doWithLock);
virtual BBinder* localBinder();
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 7c89759e17..c69bb9e744 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -76,6 +76,7 @@ public:
object_cleanup_func func) final;
virtual void* findObject(const void* objectID) const final;
virtual void* detachObject(const void* objectID) final;
+ void withLock(const std::function<void()>& doWithLock);
virtual BpBinder* remoteBinder();
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 4e0952f653..c484d8347c 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -22,6 +22,8 @@
#include <utils/String16.h>
#include <utils/Vector.h>
+#include <functional>
+
// linux/binder.h defines this, but we don't want to include it here in order to
// avoid exporting the kernel headers
#ifndef B_PACK_CHARS
@@ -273,6 +275,14 @@ public:
*/
virtual void* detachObject(const void* objectID) = 0;
+ /**
+ * Use the lock that this binder contains internally. For instance, this can
+ * be used to modify an attached object without needing to add an additional
+ * lock (though, that attached object must be retrieved before calling this
+ * method). Calling (most) IBinder methods inside this will deadlock.
+ */
+ void withLock(const std::function<void()>& doWithLock);
+
virtual BBinder* localBinder();
virtual BpBinder* remoteBinder();