diff options
author | 2018-12-04 16:28:34 +0000 | |
---|---|---|
committer | 2018-12-04 16:28:34 +0000 | |
commit | 2fcf06a23bc87f94b42ccbedc7e37fa82d2d7bd3 (patch) | |
tree | a16e12c8eae67c7b45b4fe44f56be8df7ffab458 | |
parent | 2a2896c2808d8d51ed6f8a2b458f3c0971fe9cf7 (diff) | |
parent | 0b940847d62a25bc0f24e6199971c1782de55170 (diff) |
Merge "Fixed deadlock while mapping and unmapping process in AMS"
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 58 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ProcessList.java | 14 |
2 files changed, 45 insertions, 27 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0e354d515eef..562e80d906b1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -666,16 +666,50 @@ 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) { - mPidMap.put(key, 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) { - mPidMap.remove(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); - } + 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); - } + 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); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 7991783e08c8..62f100926581 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -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); - } + 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*/); } + mService.mPidsSelfLocked.put(pid, app); synchronized (mService.mPidsSelfLocked) { - mService.mPidsSelfLocked.put(pid, app); 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.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); |