JNIHelper :: ~JNIHelper() { JNIEnv *env; processCallbacks(&mInitializationCallbacks, 0, false); processCallbacks(&mTerminationCallbacks, mCachedVM, true); env = this->getEnv(); if (env) { if (mOutOfMemoryErrorSingleton) { env->DeleteGlobalRef(mOutOfMemoryErrorSingleton); mOutOfMemoryErrorSingleton = 0; } if (mJNIPointerReference_class) { // Tell the JVM we're done with it. env->DeleteWeakGlobalRef(mJNIPointerReference_class); mJNIPointerReference_class = 0; } if (mThread_class) { env->DeleteWeakGlobalRef(mThread_class); mThread_class = 0; } if (mInterruptedException_class) { env->DeleteWeakGlobalRef(mInterruptedException_class); mInterruptedException_class = 0; } } mCachedVM = 0; }
////////////////////////////////////////////////////////////////////////// // update //virtual void CsCore::update() { // Should be handled in CsPackage. Look into doing it. processCreateResources(); processLoadingResources(); processLoadedResource(); processUnloadingResources(); processCallbacks(); }
void JNIHelper :: setVM(JavaVM * jvm) { if (!mCachedVM) { mCachedVM = jvm; // Now, let's cache the commonly used classes. JNIEnv *env=this->getEnv(); // It can be helpful to attach a GDB or Debugger to // a Running JVM. This function attempts to see if that's // required. waitForDebugger(env); jclass cls=0; // let's set up a singleton out of memory error for potential // reuse later cls = env->FindClass("java/lang/OutOfMemoryError"); if (!cls || env->ExceptionCheck()) return; jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V"); if (!constructor || env->ExceptionCheck()) return; jstring errorMessage = env->NewStringUTF( "Sorry, but we're all out of native memory. How out" " of native memory are we? Well, we're so out we're" " throwing a exception we allocated at" " the beginning of program time, so while the stack trace will" " be wrong, at least you get some useful feedback"); if (!errorMessage) return; jthrowable exception=static_cast<jthrowable>( env->NewObject(cls, constructor, errorMessage)); env->DeleteLocalRef(errorMessage); if (!exception) { return; } mOutOfMemoryErrorSingleton = static_cast<jthrowable>(env->NewGlobalRef(exception)); if (!mOutOfMemoryErrorSingleton || env->ExceptionCheck()) return; env->DeleteLocalRef(cls); cls = env->FindClass("io/humble/ferry/JNIPointerReference"); if (!cls || env->ExceptionCheck()) return; // Keep a reference around mJNIPointerReference_class=env->NewWeakGlobalRef(cls); if (!mJNIPointerReference_class || env->ExceptionCheck()) return; // Now, look for our get and set mehods. mJNIPointerReference_setPointer_mid = env->GetMethodID(cls, "setPointer", "(J)J"); if (!mJNIPointerReference_setPointer_mid || env->ExceptionCheck()) return; mJNIPointerReference_getPointer_mid = env->GetMethodID(cls, "getPointer", "()J"); if (!mJNIPointerReference_getPointer_mid || env->ExceptionCheck()) return; env->DeleteLocalRef(cls); cls = env->FindClass("io/humble/ferry/JNIThreadProxy"); if (!cls || env->ExceptionCheck()) return; // Keep a reference around mThread_class=env->NewWeakGlobalRef(cls); if (!mThread_class || env->ExceptionCheck()) return; // now look for the isInterrupted method mThread_currentThread_mid = env->GetStaticMethodID(cls, "currentThread", "()Ljava/lang/Thread;"); if (!mThread_currentThread_mid || env->ExceptionCheck()) return; mThread_isInterrupted_mid = env->GetMethodID(cls, "isInterrupted", "()Z"); if (!mThread_isInterrupted_mid || env->ExceptionCheck()) return; mThread_interrupt_mid = env->GetMethodID(cls, "interrupt", "()V"); if (!mThread_interrupt_mid || env->ExceptionCheck()) return; env->DeleteLocalRef(cls); // Are there any pending callbacks? processCallbacks(&mInitializationCallbacks, mCachedVM, true); // And Initialize the JNI Memory manager; // This means that any callbacks will NOT use the // JVM for memory management. VSJNI_MemoryManagerInit(mCachedVM); } }