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

Commit d11e1606 authored by Ray Essick's avatar Ray Essick
Browse files

Improve handling MediaCodec linkToDeath() resource manager

manage use of service pointer from MediaCodec to resource manager
to avoid race conditions during teardown.

Bug: 173791720
Test: manual audit since repo is unreliable
Merged-In: I7436e064b63a9b1833f0a2126319674d5ab50828
Change-Id: I843c2f5442557b64babdbba80fc1afd10d2ec5cb
parent dccdc011
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#define LOG_TAG "MediaCodec"
#include <utils/Log.h>

#include <set>

#include <inttypes.h>
#include <stdlib.h>

@@ -201,6 +203,10 @@ struct MediaCodec::ResourceManagerServiceProxy : public RefBase {
    // implements DeathRecipient
    static void BinderDiedCallback(void* cookie);
    void binderDied();
    static Mutex sLockCookies;
    static std::set<void*> sCookies;
    static void addCookie(void* cookie);
    static void removeCookie(void* cookie);

    void addResource(const MediaResourceParcel &resource);
    void removeResource(const MediaResourceParcel &resource);
@@ -227,8 +233,15 @@ MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
}

MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {

    // remove the cookie, so any in-flight death notification will get dropped
    // by our handler.
    removeCookie(this);

    Mutex::Autolock _l(mLock);
    if (mService != nullptr) {
        AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
        mService = nullptr;
    }
}

@@ -240,14 +253,37 @@ void MediaCodec::ResourceManagerServiceProxy::init() {
        return;
    }

    // so our handler will process the death notifications
    addCookie(this);

    // after this, require mLock whenever using mService
    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
}

//static
Mutex MediaCodec::ResourceManagerServiceProxy::sLockCookies;
std::set<void*> MediaCodec::ResourceManagerServiceProxy::sCookies;

//static
void MediaCodec::ResourceManagerServiceProxy::addCookie(void* cookie) {
    Mutex::Autolock _l(sLockCookies);
    sCookies.insert(cookie);
}

//static
void MediaCodec::ResourceManagerServiceProxy::removeCookie(void* cookie) {
    Mutex::Autolock _l(sLockCookies);
    sCookies.erase(cookie);
}

//static
void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) {
    Mutex::Autolock _l(sLockCookies);
    if (sCookies.find(cookie) != sCookies.end()) {
        auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
        thiz->binderDied();
    }
}

void MediaCodec::ResourceManagerServiceProxy::binderDied() {
    ALOGW("ResourceManagerService died.");