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

Commit 57d90982 authored by Ray Essick's avatar Ray Essick Committed by android-build-team Robot
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
(cherry picked from commit d11e1606)
parent 0025b691
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,17 +253,40 @@ 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);

    // Kill clients pending removal.
    mService->reclaimResourcesFromClientsPendingRemoval(mPid);
}

//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.");