Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 402c8676 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Fix defaultServiceManager() locking and retry loop.

Use a static instead of double-checked locking.

Bug: 142838845
Test: builds
Change-Id: I0b42539cae70a70c6a23798c27f6b088bb5d3b40
parent fde69639
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -85,31 +85,36 @@ private:
    sp<AidlServiceManager> mTheRealServiceManager;
};

static Mutex gDefaultServiceManagerLock;
static std::once_flag gSmOnce;
static sp<IServiceManager> gDefaultServiceManager;

sp<IServiceManager> defaultServiceManager()
{

    if (gDefaultServiceManager != nullptr) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == nullptr) {
            gDefaultServiceManager = new ServiceManagerShim(
                interface_cast<AidlServiceManager>(
                    ProcessState::self()->getContextObject(nullptr)));
            if (gDefaultServiceManager == nullptr)
    std::call_once(gSmOnce, []() {
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            if (sm == nullptr) {
                sleep(1);
            }
        }

        gDefaultServiceManager = new ServiceManagerShim(sm);
    });

    return gDefaultServiceManager;
}

void setDefaultServiceManager(const sp<IServiceManager>& sm) {
  AutoMutex _l(gDefaultServiceManagerLock);
    bool called = false;
    std::call_once(gSmOnce, [&]() {
        gDefaultServiceManager = sm;
        called = true;
    });

    if (!called) {
        LOG_ALWAYS_FATAL("setDefaultServiceManager() called after defaultServiceManager().");
    }
}

#if !defined(__ANDROID_VNDK__) && defined(__ANDROID__)
+3 −0
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ sp<IServiceManager> defaultServiceManager();

/**
 * Directly set the default service manager. Only used for testing.
 * Note that the caller is responsible for caling this method
 * *before* any call to defaultServiceManager(); if the latter is
 * called first, setDefaultServiceManager() will abort.
 */
void setDefaultServiceManager(const sp<IServiceManager>& sm);