summaryrefslogtreecommitdiffstats
path: root/java/jni
diff options
context:
space:
mode:
authorPetre Eftime <[email protected]>2016-07-06 15:40:38 +0300
committerPetre Eftime <[email protected]>2016-07-06 15:40:50 +0300
commit0f7e2a074f71c827ac6092fdd0b80946a83bdf7d (patch)
tree06b50f07fc385c5ac11654398c4e8efe46b335f0 /java/jni
parent5f86e56bf3f9dc5091322f2366f30e6ed73e1128 (diff)
java: Refactor JNIMem classes
Signed-off-by: Petre Eftime <[email protected]>
Diffstat (limited to 'java/jni')
-rw-r--r--java/jni/JNIMem.cxx43
-rw-r--r--java/jni/JNIMem.hpp68
2 files changed, 71 insertions, 40 deletions
diff --git a/java/jni/JNIMem.cxx b/java/jni/JNIMem.cxx
index 62ba1c27..f13a8c85 100644
--- a/java/jni/JNIMem.cxx
+++ b/java/jni/JNIMem.cxx
@@ -31,3 +31,46 @@ jint JNI_OnLoad(JavaVM *initVM, void *reserved) {
vm = initVM;
return JNI_VERSION_1_8;
}
+
+JNIEnv *JNIEnvContainer::operator*() {
+ attach();
+ return env;
+}
+
+JNIEnv *JNIEnvContainer::operator->() {
+ attach();
+ return env;
+}
+
+JNIEnvContainer::JNIEnvContainer() {}
+
+JNIEnvContainer::~JNIEnvContainer() {
+ detach();
+}
+
+void JNIEnvContainer::attach() {
+ if (env != nullptr)
+ return;
+ jint err = vm->AttachCurrentThreadAsDaemon((void **)&env, NULL);
+ if (err != JNI_OK)
+ throw std::runtime_error("Attach to VM failed");
+}
+
+void JNIEnvContainer::detach() {
+ if (env == nullptr)
+ return;
+ vm->DetachCurrentThread();
+ env = nullptr;
+}
+
+JNIGlobalRef::JNIGlobalRef(jobject object) {
+ this->object = jni_env->NewGlobalRef(object);
+}
+
+JNIGlobalRef::~JNIGlobalRef() {
+ jni_env->DeleteGlobalRef(object);
+}
+
+jobject JNIGlobalRef::operator*() {
+ return object;
+}
diff --git a/java/jni/JNIMem.hpp b/java/jni/JNIMem.hpp
index e72c49cb..d4e0e33d 100644
--- a/java/jni/JNIMem.hpp
+++ b/java/jni/JNIMem.hpp
@@ -28,62 +28,50 @@
extern JavaVM* vm;
+
+/*
+ * This class provides a lifetime-managed JNIEnv object, which attaches or
+ * detaches the current thread from the JVM automatically
+ */
class JNIEnvContainer {
private:
JNIEnv *env = nullptr;
public:
- JNIEnv *operator*() {
- attach();
- return env;
- }
-
- JNIEnv *operator->() {
- attach();
- return env;
- }
-
- JNIEnvContainer() {
- }
-
- ~JNIEnvContainer() {
- detach();
- }
+ /* Attaches this thread to the JVM if it is not already attached */
+ JNIEnvContainer();
+ /* Detaches this thread to the JVM if it is attached */
+ ~JNIEnvContainer();
- void attach() {
- if (env != nullptr)
- return;
- jint err = vm->AttachCurrentThreadAsDaemon((void **)&env, NULL);
- if (err != JNI_OK)
- throw std::runtime_error("Attach to VM failed");
- }
+ /* Provides access to the local thread's JNIEnv object */
+ JNIEnv *operator*();
+ /* Provides access to the local thread's JNIEnv object's methods */
+ JNIEnv *operator->();
- void detach() {
- if (env == nullptr)
- return;
- vm->DetachCurrentThread();
- env = nullptr;
- }
+ /* Attaches this thread to the JVM if it is not already attached */
+ void attach();
+ /* Detaches this thread to the JVM if it is attached */
+ void detach();
};
+/* Each thread has a local jni_env variable of JNIEnvContainer type */
extern thread_local JNIEnvContainer jni_env;
+/*
+ * This class provides a lifetime-managed GlobalRef variable, which is automatically
+ * deleted when it goes out of scope.
+ */
class JNIGlobalRef {
private:
jobject object;
public:
-
- JNIGlobalRef(jobject object) {
- this->object = jni_env->NewGlobalRef(object);
- }
-
- ~JNIGlobalRef() {
- jni_env->DeleteGlobalRef(object);
- }
+ /* Creates a GlobalRef from an object passed to it */
+ JNIGlobalRef(jobject object);
+ /* Deletes the stored GlobalRef */
+ ~JNIGlobalRef();
- jobject operator*() {
- return object;
- }
+ /* Provides access to the stored GlobalRef */
+ jobject operator*();
};