You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/01/14 04:48:37 UTC
svn commit: r1557925 - in /subversion/trunk/subversion/bindings/javahl:
native/JNIUtil.cpp native/JNIUtil.h native/jniwrapper/jni_base.cpp
native/org_apache_subversion_javahl_NativeResources.cpp
src/org/apache/subversion/javahl/NativeResources.java
Author: brane
Date: Tue Jan 14 03:48:36 2014
New Revision: 1557925
URL: http://svn.apache.org/r1557925
Log:
Move the JavaHL native library initialization into a context that
is guaranteed to be single-threaded.
[in subversion/bindings/javahl]
* src/org/apache/subversion/javahl/NativeResources.java
(NativeResources.initNativeLibrary): Remove native method.
(NativeResources.init): Remove call to initNativeLibrary.
* native/JNIUtil.h (JNIUtil::JNIGlobalInit): Make method private.
(initialize_jni_util): Declare as friend.
(JNIUtil::g_inInit, JNIUtil::g_initEnv): Remove.
* javahl/native/JNIUtil.cpp
(JNIUtil::g_inInit, JNIUtil::g_initEnv): Remove.
(GlobalInitGuard): Remove.
(JNIUtil::JNIGlobalInit): Remove obsolete references to the above.
(initialize_jni_util): Implement as a wrapper for JNIUtil::JNIGlobalInit.
* native/jniwrapper/jni_base.cpp
(initialize_jni_util): Declare prototype here.
(JNI_OnLoad): Call initialize_jni_util and handle the failure here.
* native/org_apache_subversion_javahl_NativeResources.cpp:
Removed obsolete native implementation.
Removed:
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_NativeResources.cpp
Modified:
subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp
subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h
subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java
Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1557925&r1=1557924&r2=1557925&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp Tue Jan 14 03:48:36 2014
@@ -73,8 +73,6 @@ JNIMutex *JNIUtil::g_finalizedObjectsMut
JNIMutex *JNIUtil::g_logMutex = NULL;
JNIMutex *JNIUtil::g_configMutex = NULL;
bool JNIUtil::g_initException;
-bool JNIUtil::g_inInit;
-JNIEnv *JNIUtil::g_initEnv;
int JNIUtil::g_logLevel = JNIUtil::noLog;
std::ofstream JNIUtil::g_logStream;
@@ -113,109 +111,19 @@ bool JNIUtil::JNIInit(JNIEnv *env)
return true;
}
-namespace
+/* Forwarder for calling JNIGlobalInit from JNI_OnLoad(). */
+bool initialize_jni_util(JNIEnv *env)
{
-struct GlobalInitGuard
-{
- enum InitState
- {
- state_null,
- state_init,
- state_done,
- state_error
- };
-
- GlobalInitGuard()
- : m_finished(false),
- m_state(InitState(svn_atomic_cas(&m_global_state,
- state_init, state_null)))
- {
- switch (m_state)
- {
- case state_null:
- // This thread won the initialization contest.
- break;
-
- case state_done:
- // The library is already initialized.
- break;
-
- case state_init:
- // Another thread is currently initializing the
- // library. Spin and wait for it to finish, with exponential
- // backoff, but no longer than half a second.
- for (unsigned shift = 0;
- m_state == state_init && shift < 8;
- ++shift)
- {
- apr_sleep((APR_USEC_PER_SEC / 1000) << shift);
- m_state = InitState(svn_atomic_cas(&m_global_state,
- state_null, state_null));
- }
- if (m_state == state_init)
- // The initialization didn't complete in half a second,
- // which probably implies a thread crash or a deadlock.
- m_state = state_error;
- break;
-
- default:
- // Error state, or unknown state. In any case, do not continue.
- m_state = state_error;
- }
- }
-
- ~GlobalInitGuard()
- {
- // Signal the end of the library intialization if we're the
- // initializing thread.
- if (m_finished && m_state == state_null)
- {
- SVN_ERR_ASSERT_NO_RETURN(
- state_init == svn_atomic_cas(&m_global_state,
- state_done, state_init));
- }
- }
-
- bool done() const
- {
- return (m_state == state_done);
- }
-
- bool error() const
- {
- return (m_state == state_error);
- }
-
- void finish()
- {
- m_finished = true;
- }
-
-private:
- bool m_finished;
- InitState m_state;
- static volatile svn_atomic_t m_global_state;
-};
-volatile svn_atomic_t
-GlobalInitGuard::m_global_state = GlobalInitGuard::state_null;
-} // anonymous namespace
+ return JNIUtil::JNIGlobalInit(env);
+}
/**
* Initialize the environment for all requests.
+ * This method must be called in a single-threaded context.
* @param env the JNI environment for this request
*/
bool JNIUtil::JNIGlobalInit(JNIEnv *env)
{
- // This method has to be run only once during the run a program.
- GlobalInitGuard guard;
- if (guard.done())
- return true;
- else if (guard.error())
- return false;
-
- g_inInit = true;
- g_initEnv = env;
-
svn_error_t *err;
/* This has to happen before any pools are created. */
@@ -325,10 +233,6 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
if (isExceptionThrown())
return false;
- g_initEnv = NULL;
- g_inInit = false;
-
- guard.finish();
return true;
}
Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h?rev=1557925&r1=1557924&r2=1557925&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h Tue Jan 14 03:48:36 2014
@@ -147,7 +147,6 @@ class JNIUtil
}
static apr_pool_t *getPool();
- static bool JNIGlobalInit(JNIEnv *env);
static bool JNIInit(JNIEnv *env);
static bool initializeJNIRuntime();
enum { noLog, errorLog, exceptionLog, entryLog } LogLevel;
@@ -158,6 +157,9 @@ class JNIUtil
static JNIMutex *g_configMutex;
private:
+ friend bool initialize_jni_util(JNIEnv *env);
+ static bool JNIGlobalInit(JNIEnv *env);
+
static void wrappedHandleSVNError(svn_error_t *err, jthrowable jcause);
static void putErrorsInTrace(svn_error_t *err,
std::vector<jobject> &stackTrace);
@@ -194,17 +196,6 @@ class JNIUtil
static bool g_initException;
/**
- * Flag, that one thread is in the init code. Cannot use mutex
- * here since apr is not initialized yet.
- */
- static bool g_inInit;
-
- /**
- * The JNI environment used during initialization.
- */
- static JNIEnv *g_initEnv;
-
- /**
* The stream to write log messages to.
*/
static std::ofstream g_logStream;
Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp?rev=1557925&r1=1557924&r2=1557925&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp Tue Jan 14 03:48:36 2014
@@ -33,6 +33,7 @@
#include "jni_stack.hpp"
#include "../JNIUtil.h"
+bool initialize_jni_util(JNIEnv *env);
// Global library initializaiton
@@ -45,6 +46,7 @@ JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM* jvm, void*)
{
::Java::Env::static_init(jvm);
+ const ::Java::Env env;
const apr_status_t status = apr_initialize();
if (!status)
@@ -55,9 +57,16 @@ JNI_OnLoad(JavaVM* jvm, void*)
std::strcpy(buf, "Could not initialize APR: ");
const std::size_t offset = std::strlen(buf);
apr_strerror(status, buf + offset, sizeof(buf) - offset - 1);
- const ::Java::Env env;
env.ThrowNew(env.FindClass("java/lang/Error"), buf);
}
+
+ // Initialize the old-style JavaHL infrastructure.
+ if (!initialize_jni_util(env.get()) && !env.ExceptionCheck())
+ {
+ env.ThrowNew(env.FindClass("java/lang/LinkageError"),
+ "Native library initialization failed");
+ }
+
return JNI_VERSION_1_2;
}
Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java?rev=1557925&r1=1557924&r2=1557925&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java Tue Jan 14 03:48:36 2014
@@ -141,9 +141,6 @@ public class NativeResources
*/
private static final void init()
{
- if (!initNativeLibrary())
- throw new LinkageError("Native library initialization failed");
-
version = new Version();
if (!version.isAtLeast(1, 9, 0))
{
@@ -161,9 +158,4 @@ public class NativeResources
" but the run-time version is " + runtimeVersion);
}
}
-
- /**
- * Initialize the native library layer.
- */
- private static native boolean initNativeLibrary();
}