Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI - multi threads

I have a JNI wrapper for Java functions that are called from C... I'm trying to call some methods from different threads and I get an error when trying to get a new copy of the JNIEnv pointer... the code I'm using is below and is called in each method:

        JNIEnv* GetJniEnvHandle(){
        ThreadInfo();
        JNIEnv *envLoc; 
        //if(Thread::CurrentThread->IsBackground || Thread::CurrentThread->IsThreadPoolThread)  
        jint envRes = vm->GetEnv((void**)&envLoc, JNI_VERSION_1_4);
        if(envRes == JNI_OK){
            if(ThreadId != Thread::CurrentThread->ManagedThreadId)
                jint res = vm->AttachCurrentThread((void**)&envLoc, NULL);
        }else{          
            Log("Error obtaining JNIEnv* handle");  
        }
        return envLoc;
    }

The JVM has already been instantiated and this (and other methods) run when being called from the main/initial thread. When I get a value for envRes it holds a -2 when in a sub-thread.

like image 818
bbqchickenrobot Avatar asked Apr 25 '12 11:04

bbqchickenrobot


People also ask

Is JNI thread safe?

The JNI interface pointer (JNIEnv *) is only valid in the current thread. You must not pass the interface pointer from one thread to another, or cache an interface pointer and use it in multiple threads.

Is JNI fast?

When talking about JNI, there are two directions: java calling C++, and C++ calling java. Java calling C++ (or C) via the "native" keyword is very fast, around 50 clock cycles. However, C++ calling Java is somewhat slow.

What is JNI and how it works?

JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++).

What is JNI Bridge?

Introduction to Java Native Interface: Establishing a bridge between Java and C/C++ JNI (Java Native Interface) is a foreign function interface that allows code running on JVM to call (or be called by) native applications. Using JNI, one can call methods written in C/C++ or even access assembly language.


1 Answers

Please refer to the documentation to the chapter Attaching to the VM.

You need to call AttachCurrentThread() for each native thread at least once before you can use any of the JNI functions.
Thread created in Java are already attached.
So I your example whenever the GetEnv call fails call AttachCurrentThread() and you should be fine. Or make sure that whenver you create a sub thread you attach it to the VM.

like image 142
mkaes Avatar answered Oct 25 '22 14:10

mkaes