JVM Auto-Attach + Fix Thread Exiting + Fix Thread Signal Handler

This commit is contained in:
◱ PixelyIon
2020-10-17 17:08:27 +05:30
committed by ◱ PixelyIon
parent 6f2cd41470
commit 657beea070
18 changed files with 149 additions and 116 deletions

View File

@ -3,13 +3,46 @@
#include "jvm.h"
thread_local JNIEnv *env;
namespace skyline {
/*
* @brief A thread-local wrapper over JNIEnv and JavaVM which automatically handles attaching and detaching threads
*/
struct JniEnvironment {
static inline JNIEnv *env{};
static inline JavaVM *vm{};
bool attached{};
JniEnvironment(JNIEnv *environment) {
env = environment;
if (env->GetJavaVM(&vm) < 0)
throw exception("Cannot get JavaVM from environment");
}
JniEnvironment() {
if (vm) {
vm->AttachCurrentThread(&env, nullptr);
attached = true;
}
}
~JniEnvironment() {
if (vm && attached)
vm->DetachCurrentThread();
}
operator JNIEnv *() {
return env;
}
JNIEnv* operator->() {
return env;
}
};
thread_local inline JniEnvironment env;
JvmManager::JvmManager(JNIEnv *environ, jobject instance) : instance(environ->NewGlobalRef(instance)), instanceClass(reinterpret_cast<jclass>(environ->NewGlobalRef(environ->GetObjectClass(instance)))), initializeControllersId(environ->GetMethodID(instanceClass, "initializeControllers", "()V")), vibrateDeviceId(environ->GetMethodID(instanceClass, "vibrateDevice", "(I[J[I)V")), clearVibrationDeviceId(environ->GetMethodID(instanceClass, "clearVibrationDevice", "(I)V")) {
env = environ;
if (env->GetJavaVM(&vm) < 0)
throw exception("Cannot get JavaVM from environment");
env = JniEnvironment(environ);
}
JvmManager::~JvmManager() {
@ -17,16 +50,6 @@ namespace skyline {
env->DeleteGlobalRef(instance);
}
void JvmManager::AttachThread() {
if (!env)
vm->AttachCurrentThread(&env, nullptr);
}
void JvmManager::DetachThread() {
if (env)
vm->DetachCurrentThread();
}
JNIEnv *JvmManager::GetEnv() {
return env;
}