Skip to content

Commit

Permalink
Thread might actually be detached, so need to handle that
Browse files Browse the repository at this point in the history
  • Loading branch information
bostick committed May 21, 2024
1 parent dca77cb commit e32fecd
Showing 1 changed file with 51 additions and 1 deletion.
52 changes: 51 additions & 1 deletion java/jni/com_zerotierone_sdk_Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,44 @@ namespace {
bool finishInitializing();
};

//
// RAII construct for calling AttachCurrentThread and DetachCurrent automatically
//
struct ScopedJNIThreadAttacher {

JavaVM *jvm;
JNIEnv **env_p;
jint getEnvRet;

ScopedJNIThreadAttacher(JavaVM *jvmIn, JNIEnv **env_pIn, jint getEnvRetIn) :
jvm(jvmIn),
env_p(env_pIn),
getEnvRet(getEnvRetIn) {

if (getEnvRet != JNI_EDETACHED) {
return;
}

jint attachCurrentThreadRet;
if ((attachCurrentThreadRet = jvm->AttachCurrentThread(env_p, NULL)) != JNI_OK) {
LOGE("Error calling AttachCurrentThread: %d", attachCurrentThreadRet);
assert(false && "Error calling AttachCurrentThread");
}
}

~ScopedJNIThreadAttacher() {

if (getEnvRet != JNI_EDETACHED) {
return;
}

jint detachCurrentThreadRet;
if ((detachCurrentThreadRet = jvm->DetachCurrentThread()) != JNI_OK) {
LOGE("Error calling DetachCurrentThread: %d", detachCurrentThreadRet);
assert(false && "Error calling DetachCurrentThread");
}
}
};

/*
* This must return 0 on success. It can return any OS-dependent error code
Expand Down Expand Up @@ -197,11 +235,23 @@ namespace {

jint getEnvRet;
assert(ref->jvm);
if ((getEnvRet = ref->jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)) != JNI_OK) {
getEnvRet = ref->jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);

if (!(getEnvRet == JNI_OK || getEnvRet == JNI_EDETACHED)) {
LOGE("Error calling GetEnv: %d", getEnvRet);
assert(false && "Error calling GetEnv");
}

//
// Thread might actually be detached.
//
// e.g:
// https://github.com/zerotier/ZeroTierOne/blob/91e7ce87f09ac1cfdeaf6ff22c3cedcd93574c86/node/Switch.cpp#L519
//
// Make sure to attach if needed
//
ScopedJNIThreadAttacher attacher{ref->jvm, &env, getEnvRet};

if (env->ExceptionCheck()) {
LOGE("Unhandled pending exception");
return;
Expand Down

0 comments on commit e32fecd

Please sign in to comment.