Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1219)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java

Issue 2822803002: android: Post onServiceConnected to launcher thread (Closed)
Patch Set: comment Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
index 0badf0401a3e6f101744ec7deb6b5ed48a3fd3e9..1336d3df48b4d13702c679a91339b9262662b4e7 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
@@ -136,9 +136,7 @@ public class ChildProcessLauncher {
private static void freeConnection(ChildProcessConnection connection) {
assert LauncherThread.runningOnLauncherThread();
- synchronized (sSpareConnectionLock) {
- if (connection.equals(sSpareSandboxedConnection)) sSpareSandboxedConnection = null;
- }
+ if (connection == sSpareSandboxedConnection) clearSpareConnection();
// Freeing a service should be delayed. This is so that we avoid immediately reusing the
// freed service (see http://crbug.com/164069): the framework might keep a service process
@@ -184,16 +182,16 @@ public class ChildProcessLauncher {
private static Map<Integer, ChildProcessConnection> sServiceMap =
new ConcurrentHashMap<Integer, ChildProcessConnection>();
- // Lock and monitor for these members {{{
- private static final Object sSpareConnectionLock = new Object();
- // A pre-allocated and pre-bound connection ready for connection setup, or null.
+ // These variables are used for the warm up sandboxed connection.
+ // |sSpareSandboxedConnection| is non-null when there is a pending connection. Note it's cleared
+ // to null again after the connection is used for a real child process.
+ // |sSpareConnectionStarting| is true if ChildProcessConnection.StartCallback has not fired.
+ // This is used for a child process allocation to determine if StartCallback should be chained.
+ // |sSpareConnectionStartCallback| is the chained StartCallback. This is also used to determine
+ // if there is already a child process launch that's used this this connection.
private static ChildProcessConnection sSpareSandboxedConnection;
- // If sSpareSandboxedConnection is not null, this indicates whether the service is
- // ready for connection setup. Wait on the monitor lock to be notified when this
- // state changes. sSpareSandboxedConnection may be null after waiting, if starting
- // the service failed.
private static boolean sSpareConnectionStarting;
- // }}}
+ private static ChildProcessConnection.StartCallback sSpareConnectionStartCallback;
// Manages oom bindings used to bind chind services.
private static BindingManager sBindingManager = BindingManagerImpl.createBindingManager();
@@ -268,44 +266,52 @@ public class ChildProcessLauncher {
LauncherThread.post(new Runnable() {
@Override
public void run() {
- synchronized (sSpareConnectionLock) {
- if (sSpareSandboxedConnection == null) {
- ChildProcessCreationParams params = ChildProcessCreationParams.getDefault();
- sSpareConnectionStarting = true;
-
- ChildProcessConnection.StartCallback startCallback =
- new ChildProcessConnection.StartCallback() {
- @Override
- public void onChildStarted() {
- synchronized (sSpareConnectionLock) {
- sSpareConnectionStarting = false;
- sSpareConnectionLock.notify();
- }
- }
-
- @Override
- public void onChildStartFailed() {
- Log.e(TAG, "Failed to warm up the spare sandbox service");
- synchronized (sSpareConnectionLock) {
- sSpareSandboxedConnection = null;
- sSpareConnectionStarting = false;
- sSpareConnectionLock.notify();
- }
- }
- };
- ChildSpawnData spawnData = new ChildSpawnData(context,
- null /* commandLine */, -1 /* child process id */,
- null /* filesToBeMapped */, null /* launchCallback */,
- null /* child process callback */, true /* inSandbox */,
- SPARE_CONNECTION_ALWAYS_IN_FOREGROUND, params);
- sSpareSandboxedConnection = allocateBoundConnection(
- spawnData, startCallback, true /* forWarmUp */);
- }
- }
+ if (sSpareSandboxedConnection != null) return;
+ ChildProcessCreationParams params = ChildProcessCreationParams.getDefault();
+
+ ChildProcessConnection.StartCallback startCallback =
+ new ChildProcessConnection.StartCallback() {
+ @Override
+ public void onChildStarted() {
+ assert LauncherThread.runningOnLauncherThread();
+ sSpareConnectionStarting = false;
+ if (sSpareConnectionStartCallback != null) {
+ sSpareConnectionStartCallback.onChildStarted();
+ clearSpareConnection();
+ }
+ // If there is no chained callback, that means nothing has tried to
+ // use the spare connection yet. It will be cleared when it is used
+ // for an actual child process launch.
+ }
+
+ @Override
+ public void onChildStartFailed() {
+ assert LauncherThread.runningOnLauncherThread();
+ Log.e(TAG, "Failed to warm up the spare sandbox service");
+ if (sSpareConnectionStartCallback != null) {
+ sSpareConnectionStartCallback.onChildStartFailed();
+ }
+ clearSpareConnection();
+ }
+ };
+ ChildSpawnData spawnData = new ChildSpawnData(context, null /* commandLine */,
+ -1 /* child process id */, null /* filesToBeMapped */,
+ null /* launchCallback */, null /* child process callback */,
+ true /* inSandbox */, SPARE_CONNECTION_ALWAYS_IN_FOREGROUND, params);
+ sSpareSandboxedConnection =
+ allocateBoundConnection(spawnData, startCallback, true /* forWarmUp */);
+ sSpareConnectionStarting = sSpareSandboxedConnection != null;
}
});
}
+ private static void clearSpareConnection() {
+ assert LauncherThread.runningOnLauncherThread();
+ sSpareSandboxedConnection = null;
+ sSpareConnectionStarting = false;
+ sSpareConnectionStartCallback = null;
+ }
+
/**
* Spawns and connects to a child process. May be called on any thread. It will not block, but
* will instead callback to {@link #nativeOnChildProcessStarted} when the connection is
@@ -372,48 +378,46 @@ public class ChildProcessLauncher {
ChildProcessConnection allocatedConnection = null;
String packageName = creationParams != null ? creationParams.getPackageName()
: context.getPackageName();
- synchronized (sSpareConnectionLock) {
- if (inSandbox && sSpareSandboxedConnection != null
- && SPARE_CONNECTION_ALWAYS_IN_FOREGROUND == alwaysInForeground
- && sSpareSandboxedConnection.getPackageName().equals(packageName)
- // Object identity check for getDefault should be enough. The default is
- // not supposed to change once set.
- && creationParams == ChildProcessCreationParams.getDefault()) {
- while (sSpareConnectionStarting) {
- try {
- sSpareConnectionLock.wait();
- } catch (InterruptedException ex) {
+ ChildProcessConnection.StartCallback startCallback =
+ new ChildProcessConnection.StartCallback() {
+ @Override
+ public void onChildStarted() {}
+
+ @Override
+ public void onChildStartFailed() {
+ assert LauncherThread.runningOnLauncherThread();
+ Log.e(TAG, "ChildProcessConnection.start failed, trying again");
+ LauncherThread.post(new Runnable() {
+ @Override
+ public void run() {
+ // The child process may already be bound to another client
+ // (this can happen if multi-process WebView is used in more
+ // than one process), so try starting the process again.
+ // This connection that failed to start has not been freed,
+ // so a new bound connection will be allocated.
+ startInternal(context, commandLine, childProcessId,
+ filesToBeMapped, launchCallback, childProcessCallback,
+ inSandbox, alwaysInForeground, creationParams);
+ }
+ });
}
- }
- allocatedConnection = sSpareSandboxedConnection;
- sSpareSandboxedConnection = null;
+ };
+
+ if (inSandbox && sSpareSandboxedConnection != null
+ && sSpareConnectionStartCallback == null
+ && SPARE_CONNECTION_ALWAYS_IN_FOREGROUND == alwaysInForeground
+ && sSpareSandboxedConnection.getPackageName().equals(packageName)
+ // Object identity check for getDefault should be enough. The default is
+ // not supposed to change once set.
+ && creationParams == ChildProcessCreationParams.getDefault()) {
+ allocatedConnection = sSpareSandboxedConnection;
+ if (sSpareConnectionStarting) {
+ sSpareConnectionStartCallback = startCallback;
+ } else {
+ clearSpareConnection();
}
}
if (allocatedConnection == null) {
- ChildProcessConnection.StartCallback startCallback =
- new ChildProcessConnection.StartCallback() {
- @Override
- public void onChildStarted() {}
-
- @Override
- public void onChildStartFailed() {
- Log.e(TAG, "ChildProcessConnection.start failed, trying again");
- LauncherThread.post(new Runnable() {
- @Override
- public void run() {
- // The child process may already be bound to another client
- // (this can happen if multi-process WebView is used in more
- // than one process), so try starting the process again.
- // This connection that failed to start has not been freed,
- // so a new bound connection will be allocated.
- startInternal(context, commandLine, childProcessId,
- filesToBeMapped, launchCallback,
- childProcessCallback, inSandbox, alwaysInForeground,
- creationParams);
- }
- });
- }
- };
ChildSpawnData spawnData = new ChildSpawnData(context, commandLine, childProcessId,
filesToBeMapped, launchCallback, childProcessCallback, inSandbox,
@@ -425,8 +429,6 @@ public class ChildProcessLauncher {
}
}
- Log.d(TAG, "Setting up connection to process: slot=%d",
- allocatedConnection.getServiceNumber());
triggerConnectionSetup(allocatedConnection, commandLine, childProcessId,
filesToBeMapped, childProcessCallback, launchCallback);
return allocatedConnection;
@@ -457,6 +459,7 @@ public class ChildProcessLauncher {
String[] commandLine, int childProcessId, FileDescriptorInfo[] filesToBeMapped,
final IBinder childProcessCallback, final LaunchCallback launchCallback) {
assert LauncherThread.runningOnLauncherThread();
+ Log.d(TAG, "Setting up connection to process: slot=%d", connection.getServiceNumber());
ChildProcessConnection.ConnectionCallback connectionCallback =
new ChildProcessConnection.ConnectionCallback() {
@Override
« no previous file with comments | « content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698