Merge \\"Reduce race when connecting to an existing content provider.\\" into nyc-dev am: 5f9afa968d
am: 3716762e38
Change-Id: Ida00a7b77605d505ed5b32ff84b69c8c9ed7564b
This commit is contained in:
@@ -1184,6 +1184,8 @@ public class Process {
|
||||
/** @hide */
|
||||
public static final int PROC_QUOTES = 0x400;
|
||||
/** @hide */
|
||||
public static final int PROC_CHAR = 0x800;
|
||||
/** @hide */
|
||||
public static final int PROC_OUT_STRING = 0x1000;
|
||||
/** @hide */
|
||||
public static final int PROC_OUT_LONG = 0x2000;
|
||||
|
||||
@@ -832,6 +832,7 @@ enum {
|
||||
PROC_COMBINE = 0x100,
|
||||
PROC_PARENS = 0x200,
|
||||
PROC_QUOTES = 0x400,
|
||||
PROC_CHAR = 0x800,
|
||||
PROC_OUT_STRING = 0x1000,
|
||||
PROC_OUT_LONG = 0x2000,
|
||||
PROC_OUT_FLOAT = 0x4000,
|
||||
@@ -933,8 +934,13 @@ jboolean android_os_Process_parseProcLineArray(JNIEnv* env, jobject clazz,
|
||||
floatsData[di] = strtof(buffer+start, &end);
|
||||
}
|
||||
if ((mode&PROC_OUT_LONG) != 0 && di < NL) {
|
||||
char* end;
|
||||
longsData[di] = strtoll(buffer+start, &end, 10);
|
||||
if ((mode&PROC_CHAR) != 0) {
|
||||
// Caller wants single first character returned as one long.
|
||||
longsData[di] = buffer[start];
|
||||
} else {
|
||||
char* end;
|
||||
longsData[di] = strtoll(buffer+start, &end, 10);
|
||||
}
|
||||
}
|
||||
if ((mode&PROC_OUT_STRING) != 0 && di < NS) {
|
||||
jstring str = env->NewStringUTF(buffer+start);
|
||||
|
||||
@@ -273,6 +273,10 @@ import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
|
||||
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
|
||||
import static android.os.Process.PROC_CHAR;
|
||||
import static android.os.Process.PROC_OUT_LONG;
|
||||
import static android.os.Process.PROC_PARENS;
|
||||
import static android.os.Process.PROC_SPACE_TERM;
|
||||
import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
|
||||
import static android.provider.Settings.Global.DEBUG_APP;
|
||||
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
|
||||
@@ -6412,7 +6416,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
|
||||
|
||||
app.makeActive(thread, mProcessStats);
|
||||
app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
|
||||
app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
|
||||
app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
|
||||
app.forcingToForeground = null;
|
||||
updateProcessForegroundLocked(app, false, false);
|
||||
@@ -10532,6 +10536,30 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
}
|
||||
|
||||
private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
|
||||
PROC_SPACE_TERM,
|
||||
PROC_SPACE_TERM|PROC_PARENS,
|
||||
PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
|
||||
};
|
||||
|
||||
private final long[] mProcessStateStatsLongs = new long[1];
|
||||
|
||||
boolean isProcessAliveLocked(ProcessRecord proc) {
|
||||
if (proc.procStatFile == null) {
|
||||
proc.procStatFile = "/proc/" + proc.pid + "/stat";
|
||||
}
|
||||
mProcessStateStatsLongs[0] = 0;
|
||||
if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
|
||||
mProcessStateStatsLongs, null)) {
|
||||
if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
|
||||
return false;
|
||||
}
|
||||
final long state = mProcessStateStatsLongs[0];
|
||||
if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
|
||||
+ (char)state);
|
||||
return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
|
||||
}
|
||||
|
||||
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
|
||||
String name, IBinder token, boolean stable, int userId) {
|
||||
ContentProviderRecord cpr;
|
||||
@@ -10619,7 +10647,16 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
|
||||
final int verifiedAdj = cpr.proc.verifiedAdj;
|
||||
boolean success = updateOomAdjLocked(cpr.proc);
|
||||
// XXX things have changed so updateOomAdjLocked doesn't actually tell us
|
||||
// if the process has been successfully adjusted. So to reduce races with
|
||||
// it, we will check whether the process still exists. Note that this doesn't
|
||||
// completely get rid of races with LMK killing the process, but should make
|
||||
// them much smaller.
|
||||
if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
|
||||
success = false;
|
||||
}
|
||||
maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
|
||||
checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
|
||||
if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
|
||||
@@ -10645,6 +10682,8 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
providerRunning = false;
|
||||
conn = null;
|
||||
} else {
|
||||
cpr.proc.verifiedAdj = cpr.proc.setAdj;
|
||||
}
|
||||
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
@@ -20081,6 +20120,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
"Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
|
||||
+ app.adjType);
|
||||
app.setAdj = app.curAdj;
|
||||
app.verifiedAdj = ProcessList.INVALID_ADJ;
|
||||
}
|
||||
|
||||
if (app.setSchedGroup != app.curSchedGroup) {
|
||||
|
||||
@@ -75,6 +75,7 @@ final class ProcessRecord {
|
||||
ProcessState baseProcessTracker;
|
||||
BatteryStatsImpl.Uid.Proc curProcBatteryStats;
|
||||
int pid; // The process of this application; 0 if none
|
||||
String procStatFile; // path to /proc/<pid>/stat
|
||||
int[] gids; // The gids this process was launched with
|
||||
String requiredAbi; // The ABI this process was launched with
|
||||
String instructionSet; // The instruction set this process was launched with
|
||||
@@ -93,6 +94,7 @@ final class ProcessRecord {
|
||||
int setRawAdj; // Last set OOM unlimited adjustment for this process
|
||||
int curAdj; // Current OOM adjustment for this process
|
||||
int setAdj; // Last set OOM adjustment for this process
|
||||
int verifiedAdj; // The last adjustment that was verified as actually being set
|
||||
int curSchedGroup; // Currently desired scheduling class
|
||||
int setSchedGroup; // Last set to background scheduling class
|
||||
int trimMemoryLevel; // Last selected memory trimming level
|
||||
@@ -441,7 +443,7 @@ final class ProcessRecord {
|
||||
pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));
|
||||
maxAdj = ProcessList.UNKNOWN_ADJ;
|
||||
curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
|
||||
curAdj = setAdj = ProcessList.INVALID_ADJ;
|
||||
curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
|
||||
persistent = false;
|
||||
removed = false;
|
||||
lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
|
||||
@@ -449,6 +451,7 @@ final class ProcessRecord {
|
||||
|
||||
public void setPid(int _pid) {
|
||||
pid = _pid;
|
||||
procStatFile = null;
|
||||
shortStringName = null;
|
||||
stringName = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user