aboutsummaryrefslogtreecommitdiffstats
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
commit217781e8322d26f9d1b31aacbd62579dc78269d4 (patch)
tree82d0b2dd15b0f52add3b8cb609b438c9003e0658
parentbc3b21d1a897e257d98c5df9dfbf88d283772e72 (diff)
java: Refactor JNIMem classes
Signed-off-by: Petre Eftime <[email protected]>
-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 62ba1c2..f13a8c8 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 e72c49c..d4e0e33 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*();
};