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

Unified Diff: content/public/android/java/src/org/chromium/content/app/LibraryLoader.java

Issue 12700011: [Android] Allow JNI initialization on background thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: [Android] Allow JNI initialization on background thread - rebase to fix landing problems Created 7 years, 9 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/app/ChildProcessService.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/app/LibraryLoader.java
diff --git a/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java b/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java
index 0facd0b31ebae5194207e36db3a03283334bb954..5791d56bbcc8dc51a5b44f6f053e499d863e1426 100644
--- a/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java
+++ b/content/public/android/java/src/org/chromium/content/app/LibraryLoader.java
@@ -15,13 +15,14 @@ import org.chromium.content.common.TraceEvent;
/**
* This class provides functionality to load and register the native library.
- * In most cases, users will call ensureInitialized() from their main thread
- * (only) which ensures a post condition that the library is loaded,
- * initialized, and ready to use.
- * Optionally, an application may optimize startup be calling loadNow early on,
- * from a background thread, and then on completion of that method it must call
- * ensureInitialized() on the main thread before it tries to access any native
- * code.
+ * Callers are allowed to separate loading the library from initializing it.
+ * This may be an advantage for Android Webview, where the library can be loaded
+ * by the zygote process, but then needs per process initialization after the
+ * application processes are forked from the zygote process.
+ *
+ * The library may be loaded and initialized from any thread. Synchronization
+ * primitives are used to ensure that overlapping requests from different
+ * threads are handled sequentially.
*/
@JNINamespace("content")
public class LibraryLoader {
@@ -30,7 +31,7 @@ public class LibraryLoader {
private static String sLibrary = null;
// This object's lock guards sLoaded assignment and also the library load.
- private static Object sLoadedLock = new Object();
+ private static Object sLoadLock = new Object();
private static Boolean sLoaded = false;
private static boolean sInitialized = false;
@@ -57,19 +58,20 @@ public class LibraryLoader {
}
/**
- * This method blocks until the library is fully loaded and initialized;
- * must be called on the thread that the native will call its "main" thread.
+ * This method blocks until the library is fully loaded and initialized.
*/
public static void ensureInitialized() throws ProcessInitException {
- checkThreadUsage();
- if (sInitialized) {
- // Already initialized, nothing to do.
- return;
+ synchronized (sLoadLock) {
+ if (sInitialized) {
+ // Already initialized, nothing to do.
+ return;
+ }
+ loadAlreadyLocked();
+ initializeAlreadyLocked(CommandLine.getJavaSwitchesOrNull());
}
- loadNow();
- initializeOnMainThread();
}
+
/**
* Loads the library and blocks until the load completes. The caller is responsible
* for subsequently calling ensureInitialized().
@@ -80,24 +82,12 @@ public class LibraryLoader {
* @throws ProcessInitException if the native library failed to load.
*/
public static void loadNow() throws ProcessInitException {
- if (sLibrary == null) {
- assert false : "No library specified to load. Call setLibraryToLoad before first.";
- }
- try {
- synchronized (sLoadedLock) {
- if (!sLoaded) {
- assert !sInitialized;
- Log.i(TAG, "loading: " + sLibrary);
- System.loadLibrary(sLibrary);
- Log.i(TAG, "loaded: " + sLibrary);
- sLoaded = true;
- }
- }
- } catch (UnsatisfiedLinkError e) {
- throw new ProcessInitException(ResultCodes.RESULT_CODE_NATIVE_LIBRARY_LOAD_FAILED, e);
+ synchronized (sLoadLock) {
+ loadAlreadyLocked();
}
}
+
/**
* initializes the library here and now: must be called on the thread that the
* native will call its "main" thread. The library must have previously been
@@ -105,12 +95,37 @@ public class LibraryLoader {
* @param initCommandLine The command line arguments that native command line will
* be initialized with.
*/
- static void initializeOnMainThread(String[] initCommandLine) throws ProcessInitException {
- checkThreadUsage();
+ static void initialize(String[] initCommandLine) throws ProcessInitException {
+ synchronized (sLoadLock) {
+ initializeAlreadyLocked(initCommandLine);
+ }
+ }
+
+
+ private static void loadAlreadyLocked() throws ProcessInitException {
+ if (sLibrary == null) {
+ assert false : "No library specified to load. Call setLibraryToLoad before first.";
+ }
+ try {
+ if (!sLoaded) {
+ assert !sInitialized;
+ Log.i(TAG, "loading: " + sLibrary);
+ System.loadLibrary(sLibrary);
+ Log.i(TAG, "loaded: " + sLibrary);
+ sLoaded = true;
+ }
+ } catch (UnsatisfiedLinkError e) {
+ throw new ProcessInitException(ResultCodes.RESULT_CODE_NATIVE_LIBRARY_LOAD_FAILED, e);
+ }
+ }
+
+
+ private static void initializeAlreadyLocked(String[] initCommandLine)
+ throws ProcessInitException {
if (sInitialized) {
return;
}
- int resultCode = nativeLibraryLoadedOnMainThread(initCommandLine);
+ int resultCode = nativeLibraryLoaded(initCommandLine);
if (resultCode != 0) {
Log.e(TAG, "error calling nativeLibraryLoadedOnMainThread");
throw new ProcessInitException(resultCode);
@@ -123,40 +138,9 @@ public class LibraryLoader {
TraceEvent.setEnabledToMatchNative();
}
- static private void initializeOnMainThread() throws ProcessInitException {
- checkThreadUsage();
- if (!sInitialized) {
- initializeOnMainThread(CommandLine.getJavaSwitchesOrNull());
- }
- }
-
- private LibraryLoader() {
- }
-
- // This asserts that calls to ensureInitialized() will happen from the
- // same thread.
- private static Object sCheckThreadLock = new Object();
- private static Thread sMyThread;
- private static void checkThreadUsage() {
- Thread currentThread = Thread.currentThread();
- synchronized (sCheckThreadLock) {
- if (sMyThread == null) {
- sMyThread = currentThread;
- } else {
- if (sMyThread != currentThread) {
- Log.e(TAG, "Threading violation detected. My thread=" + sMyThread + " id=" +
- sMyThread.getId() + " but I'm being accessed from thread=" +
- currentThread + " id=" + currentThread.getId());
- assert false;
- }
- }
- }
- }
-
- // This is the only method that is registered during System.loadLibrary, as it
- // may happen on a different thread. We then call it on the main thread to register
- // everything else.
+ // This is the only method that is registered during System.loadLibrary. We then call it
+ // to register everything else.
// Return 0 on success, otherwise return the error code from
// content/public/common/result_codes.h.
- private static native int nativeLibraryLoadedOnMainThread(String[] initCommandLine);
+ private static native int nativeLibraryLoaded(String[] initCommandLine);
}
« no previous file with comments | « content/public/android/java/src/org/chromium/content/app/ChildProcessService.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698