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

Commit 8e6b2b88 authored by Kensuke Miyagi's avatar Kensuke Miyagi
Browse files

Fix deadlock between TRMS resource reclaim and Lnb.close()

Bug: 272290709
Test: TunerTest
Change-Id: Icdc4737f27ba3d32ca9ce4874c84b40d24c2607e
parent 7922ca8b
Loading
Loading
Loading
Loading
+45 −13
Original line number Original line Diff line number Diff line
@@ -25,6 +25,8 @@ import android.hardware.tv.tuner.LnbPosition;
import android.hardware.tv.tuner.LnbTone;
import android.hardware.tv.tuner.LnbTone;
import android.hardware.tv.tuner.LnbVoltage;
import android.hardware.tv.tuner.LnbVoltage;
import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.util.Log;


import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
@@ -147,10 +149,13 @@ public class Lnb implements AutoCloseable {
    public static final int EVENT_TYPE_LNB_OVERLOAD = LnbEventType.LNB_OVERLOAD;
    public static final int EVENT_TYPE_LNB_OVERLOAD = LnbEventType.LNB_OVERLOAD;


    private static final String TAG = "Lnb";
    private static final String TAG = "Lnb";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);


    Map<LnbCallback, Executor> mCallbackMap =
    Map<LnbCallback, Executor> mCallbackMap =
            new HashMap<LnbCallback, Executor>();
            new HashMap<LnbCallback, Executor>();
    Tuner mOwner;
    Tuner mOwner;
    TunerResourceManager mTunerResourceManager;
    int mClientId;
    private final Object mCallbackLock = new Object();
    private final Object mCallbackLock = new Object();




@@ -174,6 +179,10 @@ public class Lnb implements AutoCloseable {
            }
            }
        }
        }
        setOwner(tuner);
        setOwner(tuner);
        if (mOwner != null) {
            mTunerResourceManager = mOwner.getTunerResourceManager();
            mClientId = mOwner.getClientId();
        }
    }
    }


    /**
    /**
@@ -210,6 +219,8 @@ public class Lnb implements AutoCloseable {
        Objects.requireNonNull(newOwner, "newOwner must not be null");
        Objects.requireNonNull(newOwner, "newOwner must not be null");
        synchronized (mLock) {
        synchronized (mLock) {
            mOwner = newOwner;
            mOwner = newOwner;
            mTunerResourceManager = newOwner.getTunerResourceManager();
            mClientId = newOwner.getClientId();
        }
        }
    }
    }


@@ -317,6 +328,8 @@ public class Lnb implements AutoCloseable {
     * Releases the LNB instance.
     * Releases the LNB instance.
     */
     */
    public void close() {
    public void close() {
        acquireTRMSLock("close()");
        try {
            synchronized (mLock) {
            synchronized (mLock) {
                if (mIsClosed) {
                if (mIsClosed) {
                    return;
                    return;
@@ -333,5 +346,24 @@ public class Lnb implements AutoCloseable {
                    mCallbackMap.clear();
                    mCallbackMap.clear();
                }
                }
            }
            }
        } finally {
            releaseTRMSLock();
        }
    }

    private void acquireTRMSLock(String functionNameForLog) {
        if (DEBUG) {
            Log.d(TAG, "ATTEMPT:acquireLock() in " + functionNameForLog
                    + "for clientId:" + mClientId);
        }
        if (!mTunerResourceManager.acquireLock(mClientId)) {
            Log.e(TAG, "FAILED:acquireLock() in " + functionNameForLog
                    + " for clientId:" + mClientId + " - this can cause deadlock between"
                    + " Tuner API calls and onReclaimResources()");
        }
    }

    private void releaseTRMSLock() {
        mTunerResourceManager.releaseLock(mClientId);
    }
    }
}
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -903,6 +903,9 @@ public class Tuner implements AutoCloseable {
        }
        }
    }
    }


    /**
     * Releases Lnb resource if held. TRMS lock must be acquired prior to calling this function.
     */
    private void closeLnb() {
    private void closeLnb() {
        mLnbLock.lock();
        mLnbLock.lock();
        try {
        try {
@@ -2806,6 +2809,10 @@ public class Tuner implements AutoCloseable {
        return mClientId;
        return mClientId;
    }
    }


    /* package */ TunerResourceManager getTunerResourceManager() {
        return mTunerResourceManager;
    }

    private void acquireTRMSLock(String functionNameForLog) {
    private void acquireTRMSLock(String functionNameForLog) {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "ATTEMPT:acquireLock() in " + functionNameForLog
            Log.d(TAG, "ATTEMPT:acquireLock() in " + functionNameForLog