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

Commit d2280b81 authored by jiayongqiang's avatar jiayongqiang
Browse files

Fix deadlock issue.



It might cause deadlock sometimes:

The locking order of setEventsMask is:
    registerDisplayListener -> <DMG.mLock> -> setEventsMask -> <class lock>;

The Locking order of handleMessage is:
    Looper.loop -> Looper.loopOnce -> Handler.dispatchMessage -> handleMessage -> <class lock>;

Therefore, when the registerDisplayListener is called by client,
the DisplayListenerDelegate.handleMessage also called by DMS's callback,
at this time, if the method with DMG.mLock is called in handleMessage(),
it will lead to deadlock.

Test: (For example)
Thread A:
DisplayListenerDelegate.handleMessage() -> <class lock>
DisplayListener.onDisplayChanged() -> DMG.getCompatibleDisplay() ->
DMG.getDisplayInfo() -> <DMS.mLock>

Thead B:
DMG.registerDisplayListener() -> <DMS.mLock> -> DisplayListenerDelegate.setEventsMask() -> <class lock>

Signed-off-by: default avatarjiayongqiang <jiayongqiang@xiaomi.com>
Change-Id: Ie1a8728339c16fa8f4c4f5c758821c836fa1c96b
parent 2a1dc3a8
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -908,7 +908,7 @@ public final class DisplayManagerGlobal {

    private static final class DisplayListenerDelegate extends Handler {
        public final DisplayListener mListener;
        public long mEventsMask;
        public volatile long mEventsMask;

        private final DisplayInfo mDisplayInfo = new DisplayInfo();

@@ -928,12 +928,12 @@ public final class DisplayManagerGlobal {
            removeCallbacksAndMessages(null);
        }

        public synchronized void setEventsMask(@EventsMask long newEventsMask) {
        public void setEventsMask(@EventsMask long newEventsMask) {
            mEventsMask = newEventsMask;
        }

        @Override
        public synchronized void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EVENT_DISPLAY_ADDED:
                    if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {