Thursday, May 9, 2013

JNI Detaching threads (native thread exited without detaching)


Attached thread must detact before the thread exit, when involved in Android JNI programming plus dealing with multithread usually you will facing problem like "threadid=41: native thread exited without detaching". To solved this problem is possible when use 'pthread_key_create', below is how to implement.


1. We need register a function pointer do detach the thread during JNI_Onload(), function 'detach_current_thread' will called during thread exit.

static void detach_current_thread (void *env) {
  (*java_vm)->DetachCurrentThread (java_vm);
}

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
  JNIEnv *env = NULL;
  java_vm = vm;
  if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    return 0;
  } 
  pthread_key_create (&current_jni_env, detach_current_thread);
  return JNI_VERSION_1_4;
}



2. During callback to Java, we check the current_jni_env if initialized. 

static JNIEnv *get_jni_env (void) {
JNIEnv *env;
if ((env = pthread_getspecific (current_jni_env)) == NULL) {
env = attach_current_thread ();
pthread_setspecific (current_jni_env, env);
}
return env;
}

if current_jni_env is NULL, will attach thread to VM.


That all you need to solved the "thread exited without detaching" because pthread will call detach_current_thread before exit.