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

Commit 222587c0 authored by Arun Johnson's avatar Arun Johnson
Browse files

Fix race while setting ASyncNotify callback

Holding mAsyncCallbackLock while setCallback() in
mediacodec can cause deadlock. setCallback() is done without lock
but the ASyncCallback and userdata assignments are done within
the lock so that we can respond to async callback immediatly

bug: 236908959
Change-Id: Id0d2befa8520cbd35b6265037e6481276dcb1bfc
parent 79957d47
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -529,22 +529,31 @@ media_status_t AMediaCodec_setAsyncNotifyCallback(
        AMediaCodecOnAsyncNotifyCallback callback,
        void *userdata) {

    {
        Mutex::Autolock _l(mData->mAsyncCallbackLock);

        if (mData->mAsyncNotify == NULL) {
            mData->mAsyncNotify = new AMessage(kWhatAsyncNotify, mData->mHandler);
        }
        // we set this ahead so that we can be ready
        // to receive callbacks as soon as the next call is a
        // success.
        mData->mAsyncCallback = callback;
        mData->mAsyncCallbackUserData = userdata;
    }

    // always call, codec may have been reset/re-configured since last call.
    status_t err = mData->mCodec->setCallback(mData->mAsyncNotify);
    if (err != OK) {
        {
            //The setup gone wrong. clean up the pointers.
            Mutex::Autolock _l(mData->mAsyncCallbackLock);
            mData->mAsyncCallback = {};
            mData->mAsyncCallbackUserData = nullptr;
        }
        ALOGE("setAsyncNotifyCallback: err(%d), failed to set async callback", err);
        return translate_error(err);
    }

    mData->mAsyncCallback = callback;
    mData->mAsyncCallbackUserData = userdata;

    return AMEDIA_OK;
}