JNI now tries to attach thread to JVM if g_thread_jenv not set

This commit is contained in:
Alec Grieser 2017-07-21 18:26:18 -07:00
parent 1ef77ef99a
commit 68e539164e
1 changed files with 27 additions and 6 deletions

View File

@ -38,6 +38,7 @@
#error Missing thread local storage
#endif
static JavaVM* g_jvm = 0;
static thread_local JNIEnv* g_thread_jenv = 0; // Defined for the network thread once it is running, and for any thread that has called registerCallback
static thread_local jmethodID g_IFutureCallback_call_methodID = 0;
@ -103,12 +104,6 @@ void throwParamNotNull(JNIEnv *jenv) {
extern "C" {
#endif
static void callCallback( FDBFuture* f, void* data ) {
jobject callback = (jobject)data;
g_thread_jenv->CallVoidMethod( callback, g_IFutureCallback_call_methodID );
g_thread_jenv->DeleteGlobalRef(callback);
}
// If the methods are not found, exceptions are thrown and this will return false.
// Returns TRUE on success, false otherwise.
static bool findCallbackMethods(JNIEnv *jenv) {
@ -123,6 +118,27 @@ static bool findCallbackMethods(JNIEnv *jenv) {
return true;
}
static void callCallback( FDBFuture* f, void* data ) {
if (g_thread_jenv == 0) {
// We are on an external thread and must attach to the JVM.
// Best practice is to detach at some point, but we make one
// of these per external client and cache it, so we *should*
// be fine.
if( g_jvm != 0 && g_jvm->AttachCurrentThreadAsDaemon((void **) &g_thread_jenv, JNI_NULL) == JNI_OK ) {
if( !findCallbackMethods( g_thread_jenv ) ) {
g_thread_jenv->FatalError("FDB: Could not find callback method.\n");
}
} else {
// Can't call FatalError, because we don't have a pointer to the jenv...
fprintf(stderr, "FDB: Could not attach external client thread to the JVM as daemon.\n");
}
}
jobject callback = (jobject)data;
g_thread_jenv->CallVoidMethod( callback, g_IFutureCallback_call_methodID );
g_thread_jenv->DeleteGlobalRef(callback);
}
// Attempts to throw 't', attempts to shut down the JVM if this fails.
void safeThrow( JNIEnv *jenv, jthrowable t ) {
if( jenv->Throw( t ) != 0 ) {
@ -1059,6 +1075,11 @@ JNIEXPORT void JNICALL Java_com_apple_cie_foundationdb_FDB_Network_1stop(JNIEnv
}
}
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
g_jvm = vm;
return JNI_VERSION_1_1;
}
#ifdef __cplusplus
}
#endif