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

Commit 0b940847 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Fixed deadlock while mapping and unmapping process in AMS

Re-worked code not to hold process map lock while calling ATMS to mirror
process map information.

Change-Id: I7f84f45709ea665ad9718dce50beaad7e683773f
Fixes: 120172223
Test: N/A
parent 147ab0cc
Loading
Loading
Loading
Loading
+40 −18
Original line number Diff line number Diff line
@@ -666,15 +666,49 @@ public class ActivityManagerService extends IActivityManager.Stub
    final class PidMap {
        private final SparseArray<ProcessRecord> mPidMap = new SparseArray<>();
        /**
         * Puts the process record in the map.
         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
         * method.
         */
        void put(int key, ProcessRecord value) {
            synchronized (this) {
                mPidMap.put(key, value);
            }
            mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
        }
        /**
         * Removes the process record from the map.
         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
         * method.
         */
        void remove(int pid) {
            synchronized (this) {
                mPidMap.remove(pid);
            }
            mAtmInternal.onProcessUnMapped(pid);
        }
        /**
         * Removes the process record from the map if it has a thread.
         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
         * method.
         */
        boolean removeIfNoThread(int pid) {
            boolean removed = false;
            synchronized (this) {
                final ProcessRecord app = get(pid);
                if (app != null && app.thread == null) {
                    mPidMap.remove(pid);
                    removed = true;
                }
            }
            if (removed) {
                mAtmInternal.onProcessUnMapped(pid);
            }
            return removed;
        }
        ProcessRecord get(int pid) {
            return mPidMap.get(pid);
@@ -1889,9 +1923,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                app.getWindowProcessController().setPid(MY_PID);
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.put(app.pid, app);
                }
                mProcessList.updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }
@@ -4254,14 +4286,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    private final void processStartTimedOutLocked(ProcessRecord app) {
        final int pid = app.pid;
        boolean gone = false;
        synchronized (mPidsSelfLocked) {
            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
            if (knownApp != null && knownApp.thread == null) {
                mPidsSelfLocked.remove(pid);
                gone = true;
            }
        }
        boolean gone = mPidsSelfLocked.removeIfNoThread(pid);
        if (gone) {
            Slog.w(TAG, "Process " + app + " failed to attach");
@@ -13113,11 +13138,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            return true;
        } else if (app.pid > 0 && app.pid != MY_PID) {
            // Goodbye!
            boolean removed;
            synchronized (mPidsSelfLocked) {
            mPidsSelfLocked.remove(app.pid);
            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
            if (app.isolated) {
                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+5 −9
Original line number Diff line number Diff line
@@ -1246,10 +1246,8 @@ public final class ProcessList {
        long startTime = SystemClock.elapsedRealtime();
        if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
            checkSlow(startTime, "startProcess: removing from pids map");
            synchronized (mService.mPidsSelfLocked) {
            mService.mPidsSelfLocked.remove(app.pid);
            mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
            }
            checkSlow(startTime, "startProcess: done removing from pids map");
            app.setPid(0);
        }
@@ -1767,8 +1765,8 @@ public final class ProcessList {
            mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
                    true /*replacingPid*/);
        }
        synchronized (mService.mPidsSelfLocked) {
        mService.mPidsSelfLocked.put(pid, app);
        synchronized (mService.mPidsSelfLocked) {
            if (!procAttached) {
                Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                msg.obj = app;
@@ -1928,10 +1926,8 @@ public final class ProcessList {
                .pendingStart)) {
            int pid = app.pid;
            if (pid > 0) {
                synchronized (mService.mPidsSelfLocked) {
                mService.mPidsSelfLocked.remove(pid);
                mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
                }
                mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
                if (app.isolated) {
                    mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);