From fed6db41f8ad99dcc67bcf67d745f25ec573e5fa Mon Sep 17 00:00:00 2001 From: Jon Spivack Date: Mon, 18 Nov 2019 16:43:59 -0800 Subject: Unregister Waiter in waitForService IServiceManager's waitForService relies on notifications from servicemanager. Previously it registered with servicemanager but was missing an unregister call after use. Bug: 144534962 Test: Manual (boot and dynamically start services) Change-Id: Ic25349d42168a311e9fbce576f15de4067b0cc66 --- libs/binder/IServiceManager.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'libs/binder/IServiceManager.cpp') 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 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&& f) : mF(std::move(f)) {} + ~Defer() { mF(); } + private: + std::function mF; + }; + const std::string name = String8(name16).c_str(); sp out; if (!mTheRealServiceManager->getService(name, &out).isOk()) { return nullptr; } - if(out != nullptr) return out; + if (out != nullptr) return out; sp waiter = new Waiter; if (!mTheRealServiceManager->registerForNotifications( name, waiter).isOk()) { return nullptr; } + Defer unregister ([&] { + mTheRealServiceManager->unregisterForNotifications(name, waiter); + }); while(true) { { @@ -316,7 +328,7 @@ sp 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()); } -- cgit v1.2.3-59-g8ed1b