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

Unified Diff: components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java

Issue 726013002: [Cronet] Hook up library loader, system proxy and network change notifier to async api. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Better handling of context init and shutdown races. Created 5 years, 11 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
Index: components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
index 4c7afc6c0f2278fc2be06da86220681d7d2ee5ac..aaa25fd0657d2e1e23bbca1d7210d1c55ef722a4 100644
--- a/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/CronetUrlRequestContext.java
@@ -6,6 +6,9 @@ package org.chromium.net;
import android.content.Context;
import android.os.Build;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Process;
import android.util.Log;
@@ -25,29 +28,54 @@ public class CronetUrlRequestContext extends UrlRequestContext {
private static final int LOG_VERBOSE = -2; // LOG(FATAL...INFO), VLOG(2)
static final String LOG_TAG = "ChromiumNetwork";
+ /**
+ * Synchronize access to mUrlRequestContextAdapter and shutdown routine.
+ */
+ private final Object mLock = new Object();
private long mUrlRequestContextAdapter = 0;
private Thread mNetworkThread;
+ private final ConditionVariable mInitCompleted = new ConditionVariable(false);
mmenke 2015/01/23 20:41:41 A couple lines in here that could be reformatted t
mef 2015/01/28 21:32:28 Acknowledged.
+
private AtomicInteger mActiveRequestCount = new AtomicInteger(0);
public CronetUrlRequestContext(Context context,
UrlRequestContextConfig config) {
+ CronetLibraryLoader.ensureInitialized(context, config);
nativeSetMinLogLevel(getLoggingLevel());
mUrlRequestContextAdapter = nativeCreateRequestContextAdapter(
context, config.toString());
if (mUrlRequestContextAdapter == 0) {
throw new NullPointerException("Context Adapter creation failed");
}
mmenke 2015/01/23 20:41:41 Suggest a blank line before a comment that applies
mef 2015/01/28 21:32:28 Done.
+ // Post a task to UI thread to init native Chromium URLRequestContext.
+ // TODO(xunjieli): This constructor is not supposed to be invoked on
+ // the main thread. Consider making the following code into a blocking
+ // API to handle the case where we are already on main thread.
mmenke 2015/01/23 20:41:41 Should be clearer here about what cases are bad.
mef 2015/01/28 21:32:28 Hrm, are they actually bad?
+ Runnable task = new Runnable() {
+ public void run() {
+ synchronized (mLock) {
+ // mUrlRequestContextAdapter is guaranteed to exist until
+ // initialization on main and network threads completes and
+ // initNetworkThread is called back on network thread.
+ nativeInitRequestContextOnMainThread(mUrlRequestContextAdapter);
+ mInitCompleted.open();
+ }
+ }
+ };
+ new Handler(Looper.getMainLooper()).post(task);
}
@Override
public UrlRequest createRequest(String url, UrlRequestListener listener,
Executor executor) {
- if (mUrlRequestContextAdapter == 0) {
- throw new IllegalStateException(
- "Cannot create requests on shutdown context.");
+ synchronized (mLock) {
+ if (mUrlRequestContextAdapter == 0) {
+ throw new IllegalStateException(
+ "Context is shutdown.");
mmenke 2015/01/23 20:41:41 Think this can fit on a single line.
mef 2015/01/28 21:32:28 Done.
+ }
+ return new CronetUrlRequest(this, mUrlRequestContextAdapter, url,
+ UrlRequest.REQUEST_PRIORITY_MEDIUM, listener, executor);
}
- return new CronetUrlRequest(this, mUrlRequestContextAdapter, url,
- UrlRequest.REQUEST_PRIORITY_MEDIUM, listener, executor);
}
@Override
@@ -62,28 +90,54 @@ public class CronetUrlRequestContext extends UrlRequestContext {
@Override
public void shutdown() {
- if (mActiveRequestCount.get() != 0) {
- throw new IllegalStateException(
- "Cannot shutdown with active requests.");
+ synchronized (mLock) {
mmenke 2015/01/23 20:41:41 Hrm...Still really not a fan of this. I'll see if
mef 2015/01/28 21:32:28 SG, let's chat tomorrow.
+ if (mUrlRequestContextAdapter == 0) {
+ throw new IllegalStateException(
+ "Context is already shutdown.");
+ }
+ if (mActiveRequestCount.get() != 0) {
+ throw new IllegalStateException(
+ "Cannot shutdown with active requests.");
+ }
+ // Destroying adapter stops the network thread, so it cannot be
+ // called on network thread.
+ if (Thread.currentThread() == mNetworkThread) {
+ throw new IllegalThreadStateException(
+ "Cannot shutdown from network thread.");
+ }
}
- // Destroying adapter stops the network thread, so it cannot be called
- // on network thread.
- if (Thread.currentThread() == mNetworkThread) {
- throw new IllegalThreadStateException(
- "Cannot shutdown from network thread.");
+ // Wait for init to complete on main thread (without lock, so main thread
+ // could access it).
+ mInitCompleted.block();
+
+ long urlRequestContextAdapter;
+ synchronized (mLock) {
+ urlRequestContextAdapter = mUrlRequestContextAdapter;
+ mUrlRequestContextAdapter = 0;
}
- nativeDestroyRequestContextAdapter(mUrlRequestContextAdapter);
- mUrlRequestContextAdapter = 0;
+ nativeDestroyRequestContextAdapter(urlRequestContextAdapter);
}
@Override
public void startNetLogToFile(String fileName) {
- nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName);
+ synchronized (mLock) {
+ if (mUrlRequestContextAdapter == 0) {
+ throw new IllegalStateException(
+ "Context is shutdown.");
+ }
+ nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName);
+ }
}
@Override
public void stopNetLog() {
- nativeStopNetLog(mUrlRequestContextAdapter);
+ synchronized (mLock) {
+ if (mUrlRequestContextAdapter == 0) {
+ throw new IllegalStateException(
+ "Context is shutdown.");
+ }
+ nativeStopNetLog(mUrlRequestContextAdapter);
+ }
}
/**
@@ -103,10 +157,12 @@ public class CronetUrlRequestContext extends UrlRequestContext {
}
long getUrlRequestContextAdapter() {
- if (mUrlRequestContextAdapter == 0) {
- throw new IllegalStateException("Context Adapter is destroyed.");
+ synchronized (mLock) {
+ if (mUrlRequestContextAdapter == 0) {
+ throw new IllegalStateException("Context is shutdown.");
+ }
+ return mUrlRequestContextAdapter;
}
- return mUrlRequestContextAdapter;
}
/**
@@ -128,7 +184,9 @@ public class CronetUrlRequestContext extends UrlRequestContext {
@SuppressWarnings("unused")
@CalledByNative
private void initNetworkThread() {
- mNetworkThread = Thread.currentThread();
+ synchronized (mLock) {
+ mNetworkThread = Thread.currentThread();
+ }
Thread.currentThread().setName("ChromiumNet");
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}
@@ -146,4 +204,7 @@ public class CronetUrlRequestContext extends UrlRequestContext {
private native void nativeStopNetLog(long urlRequestContextAdapter);
private native int nativeSetMinLogLevel(int loggingLevel);
+
+ private native void nativeInitRequestContextOnMainThread(
+ long urlRequestContextAdapter);
}

Powered by Google App Engine
This is Rietveld 408576698