summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();