throw std::exception();
}
}
+
+int JNIHelper::ExecuteWithEnv(JavaVM *jvm, const std::function<int(JNIEnv *, void *)> &callback, void *data)
+{
+ if (jvm == nullptr) {
+ ErrPrint("Invalid arguments, jvm(%p)", jvm);
+ return -EINVAL;
+ }
+
+ JNIEnv *env = nullptr;
+
+ int JNIStatus = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4);
+ if (JNIStatus == JNI_EDETACHED) {
+ if (jvm->AttachCurrentThread(&env, nullptr) != 0) {
+ ErrPrint("Failed to attach current thread");
+ return -EFAULT;
+ }
+ } else if (JNIStatus == JNI_EVERSION) {
+ ErrPrint("GetEnv: Unsupported version");
+ return -ENOTSUP;
+ }
+
+ if (env == nullptr) {
+ ErrPrint("Failed to get the environment object");
+ return -EFAULT;
+ }
+
+ int ret = callback(env, data);
+
+ if (JNIStatus == JNI_EDETACHED) {
+ jvm->DetachCurrentThread();
+ }
+
+ return ret;
+}
#include <cerrno>
#include <jni.h>
#include <string>
+#include <functional>
#define JNI_LONG_TYPE "J"
#define JNI_OBJECT_TYPE "Ljava/lang/Object;"
static jclass FindClass(JNIEnv *env, const char *name);
static jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *signature);
static void checkEnvException(JNIEnv *env);
+ static int ExecuteWithEnv(JavaVM *jvm, const std::function<int(JNIEnv *, void *)> &callback, void *data = nullptr);
private:
JNIHelper(void);
// It should be narrowed and simplified
// otherwise, the destructor code should be separated
if (listener != nullptr) {
- JNIEnv *env = nullptr;
- bool attached = false;
- int JNIStatus = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4);
- if (JNIStatus == JNI_EDETACHED) {
- if (jvm->AttachCurrentThread(&env, nullptr) != 0) {
- ErrPrint("Failed to attach current thread");
- } else {
- attached = true;
- }
- } else if (JNIStatus == JNI_EVERSION) {
- ErrPrint("GetEnv: Unsupported version");
- }
-
- if (env == nullptr) {
- ErrPrint("Failed to get the environment object");
- } else {
+ JNIHelper::ExecuteWithEnv(jvm, [&](JNIEnv *env, void *data) -> int {
// NOTE:
// this can be happens when the user calls "close" method directly
DbgPrint("Event listener is not cleared, forcibly delete the reference");
env->DeleteGlobalRef(listener);
listener = nullptr;
- }
-
- if (attached == true) {
- jvm->DetachCurrentThread();
- }
+ return 0;
+ });
}
jvm = nullptr;
}
if (inst->listener != nullptr) {
- JNIEnv *env = nullptr;
- bool attached = false;
- int JNIStatus;
-
- JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
- if (JNIStatus == JNI_EDETACHED) {
- if (inst->jvm->AttachCurrentThread(&env, nullptr) != 0) {
- ErrPrint("Failed to attach current thread");
- } else {
- attached = true;
- }
- } else if (JNIStatus == JNI_EVERSION) {
- ErrPrint("GetEnv: Unsupported version");
- }
-
- if (env == nullptr) {
- ErrPrint("Failed to getEnv, event cannot be delivered to the managed code");
- } else {
+ JNIHelper::ExecuteWithEnv(inst->jvm, [inst, &event](JNIEnv *env, void *data) -> int {
// NOTE:
// Now, publish the event object to the event listener
- status = inst->InvokeEventListener(env, event.type, event.data);
+ int status = inst->InvokeEventListener(env, event.type, event.data);
if (status < 0) {
ErrPrint("Failed to invoke the event listener");
}
-
- if (attached == true) {
- inst->jvm->DetachCurrentThread();
- }
- }
+ return status;
+ });
} else {
DbgPrint("Event listener is not registered");
}
}
if (listener != nullptr) {
- JNIEnv *env = nullptr;
- bool attached = false;
- int JNIStatus = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4);
- if (JNIStatus == JNI_EDETACHED) {
- if (jvm->AttachCurrentThread(&env, nullptr) != 0) {
- ErrPrint("Failed to attach current thread");
- } else {
- attached = true;
- }
- } else if (JNIStatus == JNI_EVERSION) {
- ErrPrint("GetEnv: Unsupported version");
- }
-
- if (env == nullptr) {
- ErrPrint("Failed to get the environment object");
- } else {
+ JNIHelper::ExecuteWithEnv(jvm, [&](JNIEnv *env, void *data) -> int {
// NOTE:
// this can be happens when the user calls "close" method directly
DbgPrint("Event listener is not cleared, forcibly delete the reference");
env->DeleteGlobalRef(listener);
listener = nullptr;
- }
-
- if (attached == true) {
- jvm->DetachCurrentThread();
- }
+ return 0;
+ });
}
jvm = nullptr;
}
if (inst->listener != nullptr) {
- JNIEnv *env = nullptr;
- int JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
- if (JNIStatus == JNI_OK) {
+ JNIHelper::ExecuteWithEnv(inst->jvm, [inst, &event](JNIEnv *env, void *data) -> int {
// NOTE:
// Now, publish the event object to the event listener
- status = inst->InvokeEventListener(env, event.type, event.data);
+ int status = inst->InvokeEventListener(env, event.type, event.data);
if (status < 0) {
ErrPrint("Failed to invoke the event listener");
}
- } else if (JNIStatus == JNI_EDETACHED) {
- if (inst->jvm->AttachCurrentThread(&env, nullptr) == 0) {
- // NOTE:
- // Now, publish the event object to the event listener
- status = inst->InvokeEventListener(env, event.type, event.data);
- if (status < 0) {
- ErrPrint("Failed to invoke the event listener");
- }
-
- inst->jvm->DetachCurrentThread();
- } else {
- ErrPrint("Failed to attach current thread");
- }
- } else if (JNIStatus == JNI_EVERSION) {
- ErrPrint("GetEnv: Unsupported version");
- }
+ return status;
+ });
} else {
DbgPrint("EventListener is not registered");
}