diff options
| -rw-r--r-- | libs/binder/Binder.cpp | 19 | ||||
| -rw-r--r-- | libs/binder/BpBinder.cpp | 5 | ||||
| -rw-r--r-- | libs/binder/include/binder/Binder.h | 1 | ||||
| -rw-r--r-- | libs/binder/include/binder/BpBinder.h | 1 | ||||
| -rw-r--r-- | libs/binder/include/binder/IBinder.h | 10 |
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(); |