diff options
| author | 2021-06-25 21:30:23 +0000 | |
|---|---|---|
| committer | 2021-06-25 22:41:02 +0000 | |
| commit | 9e759e81a53bd0f5027f3a0a37661206d46774a3 (patch) | |
| tree | 21e3d712b38971baef5f86ca603ad3e8161d2a59 | |
| parent | 2505ec424c80132755372cb0e8cb4e65f8d9fae1 (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.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(); |