summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Spivack <spivack@google.com>2019-11-20 19:32:49 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-11-20 19:32:49 +0000
commite395da30584636114dd77c8dd0cf3c7560305ee8 (patch)
tree4f7e8925db0c2febe190c6f3992eac13debb0b28
parente07aecf72e1c9e95553f3f33368b7d4fa87c894f (diff)
parentfed6db41f8ad99dcc67bcf67d745f25ec573e5fa (diff)
downloadnative-e395da30584636114dd77c8dd0cf3c7560305ee8.tar.gz
Merge "Unregister Waiter in waitForService"
-rw-r--r--libs/binder/IServiceManager.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 4f47db199e..bac8b6604b 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -280,19 +280,31 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16)
std::condition_variable mCv;
};
+ // Simple RAII object to ensure a function call immediately before going out of scope
+ class Defer {
+ public:
+ Defer(std::function<void()>&& f) : mF(std::move(f)) {}
+ ~Defer() { mF(); }
+ private:
+ std::function<void()> mF;
+ };
+
const std::string name = String8(name16).c_str();
sp<IBinder> out;
if (!mTheRealServiceManager->getService(name, &out).isOk()) {
return nullptr;
}
- if(out != nullptr) return out;
+ if (out != nullptr) return out;
sp<Waiter> waiter = new Waiter;
if (!mTheRealServiceManager->registerForNotifications(
name, waiter).isOk()) {
return nullptr;
}
+ Defer unregister ([&] {
+ mTheRealServiceManager->unregisterForNotifications(name, waiter);
+ });
while(true) {
{
@@ -316,7 +328,7 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16)
if (!mTheRealServiceManager->getService(name, &out).isOk()) {
return nullptr;
}
- if(out != nullptr) return out;
+ if (out != nullptr) return out;
ALOGW("Waited one second for %s", name.c_str());
}