internal static jint DetachCurrentThread(JavaVM* pJVM) { if(TlsHack.ManagedJNIEnv == null) { // the JDK allows detaching from an already detached thread return JNIEnv.JNI_OK; } // TODO if we set Thread.IsBackground to false when we attached, now might be a good time to set it back to true. JNIEnv.FreeJNIEnv(); IKVM.NativeCode.java.lang.VMThread.jniDetach(); return JNIEnv.JNI_OK; }
internal static jint GetEnv(JavaVM* pJVM, void **penv, jint version) { if(JNI.IsSupportedJniVersion(version)) { JNIEnv.ManagedJNIEnv env = TlsHack.ManagedJNIEnv; if(env != null) { *penv = env.pJNIEnv; return JNIEnv.JNI_OK; } *penv = null; return JNIEnv.JNI_EDETACHED; } *penv = null; return JNIEnv.JNI_EVERSION; }
internal static jint AttachCurrentThreadImpl(JavaVM* pJVM, void** penv, JavaVMAttachArgs* pAttachArgs, bool asDaemon) { if(pAttachArgs != null) { if(!JNI.IsSupportedJniVersion(pAttachArgs->version) || pAttachArgs->version == JNIEnv.JNI_VERSION_1_1) { *penv = null; return JNIEnv.JNI_EVERSION; } } JNIEnv.ManagedJNIEnv env = TlsHack.ManagedJNIEnv; if(env != null) { *penv = env.pJNIEnv; return JNIEnv.JNI_OK; } // NOTE if we're here, it is *very* likely that the thread was created by native code and not by managed code, // but it's not impossible that the thread started life as a managed thread and if it did the changes to the // thread we're making are somewhat dubious. System.Threading.Thread.CurrentThread.IsBackground = asDaemon; if(pAttachArgs != null) { if(pAttachArgs->name != null && System.Threading.Thread.CurrentThread.Name == null) { try { System.Threading.Thread.CurrentThread.Name = JNIEnv.StringFromUTF8(pAttachArgs->name); } catch(InvalidOperationException) { // someone beat us to it... } } object threadGroup = GlobalRefs.Unwrap(pAttachArgs->group.ToInt32()); if(threadGroup != null) { IKVM.NativeCode.java.lang.Thread.AttachThreadFromJni(threadGroup); } } *penv = JNIEnv.CreateJNIEnv(); return JNIEnv.JNI_OK; }
internal static jint AttachCurrentThread(JavaVM* pJVM, void **penv, void *args) { return AttachCurrentThreadImpl(pJVM, penv, (JavaVMAttachArgs*)args, false); }
internal static jint DestroyJavaVM(JavaVM* pJVM) { if(JNI.jvmDestroyed) { return JNIEnv.JNI_ERR; } JNI.jvmDestroyed = true; IKVM.NativeCode.java.lang.Thread.WaitUntilLastJniThread(); return JNIEnv.JNI_OK; }
internal static int GetJavaVM(JNIEnv* pEnv, JavaVM **ppJavaVM) { *ppJavaVM = JavaVM.pJavaVM; return JNI_OK; }
internal static jint DestroyJavaVM(JavaVM* pJVM) { if(JNI.jvmDestroyed) { return JNIEnv.JNI_ERR; } JNI.jvmDestroyed = true; Java_java_lang_Thread.WaitUntilLastJniThread(); return JNIEnv.JNI_OK; }