summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-11-14 14:32:17 -0800
committerDianne Hackborn <hackbod@google.com>2013-11-14 14:32:17 -0800
commitddc19e98476eec54da83b7386602443ed4aa195e (patch)
tree578b150f185b3f03ec834fe715858562b9a17c9e
parentd6f5b629216a2566883ccc6f2506fee198b07f99 (diff)
downloadbase-ddc19e98476eec54da83b7386602443ed4aa195e.tar.gz
Maybe fix issue #11634365: Leaking restarting services
It looks like we could add services to the restart list because they end up left in the process's list of running services after they have been removed from the main activity list, and we can trip up on them there when the app is being force stopped. Change-Id: I79805b67fcf5b593430dc5c856c97927e1a54a57
-rw-r--r--services/java/com/android/server/am/ActiveServices.java21
1 files changed, 20 insertions, 1 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index a80afbc562fc..933247e1f687 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -1847,6 +1847,9 @@ public final class ActiveServices {
}
}
if (finishing) {
+ if (r.app != null) {
+ r.app.services.remove(r);
+ }
r.app = null;
}
}
@@ -1927,6 +1930,7 @@ public final class ActiveServices {
Slog.i(TAG, " Force stopping service " + service);
if (service.app != null) {
service.app.removed = true;
+ service.app.services.remove(service);
}
service.app = null;
service.isolatedProc = null;
@@ -2028,6 +2032,9 @@ public final class ActiveServices {
synchronized (sr.stats.getBatteryStats()) {
sr.stats.stopLaunchedLocked();
}
+ if (sr.app != null) {
+ sr.app.services.remove(sr);
+ }
sr.app = null;
sr.isolatedProc = null;
sr.executeNesting = 0;
@@ -2053,11 +2060,23 @@ public final class ActiveServices {
}
app.connections.clear();
+ ServiceMap smap = getServiceMap(app.userId);
+
// Now do remaining service cleanup.
for (int i=app.services.size()-1; i>=0; i--) {
+ ServiceRecord sr = app.services.valueAt(i);
+ // Sanity check: if the service listed for the app is not one
+ // we actually are maintaining, drop it.
+ if (smap.mServicesByName.get(sr.name) != sr) {
+ ServiceRecord cur = smap.mServicesByName.get(sr.name);
+ Slog.wtf(TAG, "Service " + sr + " in process " + app
+ + " not same as in map: " + cur);
+ app.services.removeAt(i);
+ continue;
+ }
+
// Any services running in the application may need to be placed
// back in the pending list.
- ServiceRecord sr = app.services.valueAt(i);
if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
&ApplicationInfo.FLAG_PERSISTENT) == 0) {
Slog.w(TAG, "Service crashed " + sr.crashCount