Skip to content

Commit

Permalink
android: thread local env
Browse files Browse the repository at this point in the history
  • Loading branch information
weihuoya committed May 29, 2019
1 parent 3132839 commit 0dec8fe
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 71 deletions.
24 changes: 21 additions & 3 deletions Source/Android/jni/AndroidCommon/IDCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,27 @@ static jmethodID s_do_rumble;

namespace IDCache
{
JavaVM* GetJavaVM()
{
return s_java_vm;
JNIEnv* GetEnvForThread()
{
thread_local static struct OwnedEnv
{
OwnedEnv()
{
status = s_java_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
if (status == JNI_EDETACHED)
s_java_vm->AttachCurrentThread(&env, nullptr);
}

~OwnedEnv()
{
if (status == JNI_EDETACHED)
s_java_vm->DetachCurrentThread();
}

int status;
JNIEnv* env = nullptr;
} owned;
return owned.env;
}

jclass GetNativeLibraryClass()
Expand Down
2 changes: 1 addition & 1 deletion Source/Android/jni/AndroidCommon/IDCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace IDCache
{
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;

JavaVM* GetJavaVM();
JNIEnv* GetEnvForThread();

jclass GetNativeLibraryClass();
jmethodID GetDisplayAlertMsg();
Expand Down
41 changes: 4 additions & 37 deletions Source/Android/jni/MainAndroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,8 @@ bool s_have_wm_user_stop = false;
void UpdatePointer()
{
// Update touch pointer
JNIEnv* env;
int get_env_status =
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);

if (get_env_status == JNI_EDETACHED)
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);

JNIEnv* env = IDCache::GetEnvForThread();
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetUpdateTouchPointer());

if (get_env_status == JNI_EDETACHED)
IDCache::GetJavaVM()->DetachCurrentThread();
}

void Host_NotifyMapLoaded()
Expand Down Expand Up @@ -157,61 +148,37 @@ void Host_UpdateProgressDialog(const char* caption, int position, int total)

static bool MsgAlert(const char* caption, const char* text, bool yes_no, MsgType /*style*/)
{
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "%s:%s", caption, text);

// Associate the current Thread with the Java VM.
JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
JNIEnv* env = IDCache::GetEnvForThread();

// Execute the Java method.
jboolean result = env->CallStaticBooleanMethod(
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), ToJString(env, caption),
ToJString(env, text), yes_no ? JNI_TRUE : JNI_FALSE);

// Must be called before the current thread exits; might as well do it here.
IDCache::GetJavaVM()->DetachCurrentThread();

return result != JNI_FALSE;
}

static void ReportSend(std::string endpoint, std::string report)
{
// Associate the current Thread with the Java VM.
JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
JNIEnv* env = IDCache::GetEnvForThread();

jbyteArray output_array = env->NewByteArray(report.size());
jbyte* output = env->GetByteArrayElements(output_array, nullptr);
memcpy(output, report.data(), report.size());
env->ReleaseByteArrayElements(output_array, output, 0);
env->CallStaticVoidMethod(IDCache::GetAnalyticsClass(), IDCache::GetSendAnalyticsReport(),
ToJString(env, endpoint), output_array);

IDCache::GetJavaVM()->DetachCurrentThread();
}

static std::string GetAnalyticValue(std::string key)
{
// Associate the current Thread with the Java VM.
JNIEnv* env;
bool attached = false;
int getEnvStat =
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), IDCache::JNI_VERSION);
if (getEnvStat == JNI_EDETACHED)
{
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
attached = true;
}
JNIEnv* env = IDCache::GetEnvForThread();

jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
IDCache::GetAnalyticsClass(), IDCache::GetAnalyticsValue(), ToJString(env, key)));

std::string stdvalue = GetJString(env, value);

// Only detach the thread if it wasn't already attached
if (attached)
IDCache::GetJavaVM()->DetachCurrentThread();

return stdvalue;
}

Expand Down
17 changes: 3 additions & 14 deletions Source/Core/Core/HW/WiimoteReal/IOAndroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@ void WiimoteScannerAndroid::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,

NOTICE_LOG(WIIMOTE, "Finding Wiimotes");

JNIEnv* env;
int get_env_status =
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);

if (get_env_status == JNI_EDETACHED)
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
JNIEnv* env = IDCache::GetEnvForThread();

jmethodID openadapter_func = env->GetStaticMethodID(s_adapter_class, "OpenAdapter", "()Z");
jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");
Expand All @@ -45,9 +40,6 @@ void WiimoteScannerAndroid::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
for (int i = 0; i < MAX_WIIMOTES; ++i)
found_wiimotes.emplace_back(new WiimoteAndroid(i));
}

if (get_env_status == JNI_EDETACHED)
IDCache::GetJavaVM()->DetachCurrentThread();
}

WiimoteAndroid::WiimoteAndroid(int index) : Wiimote(), m_mayflash_index(index)
Expand All @@ -62,7 +54,7 @@ WiimoteAndroid::~WiimoteAndroid()
// Connect to a Wiimote with a known address.
bool WiimoteAndroid::ConnectInternal()
{
IDCache::GetJavaVM()->AttachCurrentThread(&m_env, nullptr);
m_env = IDCache::GetEnvForThread();

jfieldID payload_field = m_env->GetStaticFieldID(s_adapter_class, "wiimote_payload", "[[B");
jobjectArray payload_object =
Expand All @@ -81,7 +73,6 @@ bool WiimoteAndroid::ConnectInternal()

void WiimoteAndroid::DisconnectInternal()
{
IDCache::GetJavaVM()->DetachCurrentThread();
}

bool WiimoteAndroid::IsConnected() const
Expand Down Expand Up @@ -119,9 +110,7 @@ int WiimoteAndroid::IOWrite(u8 const* buf, size_t len)

void InitAdapterClass()
{
JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);

JNIEnv* env = IDCache::GetEnvForThread();
jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_WiimoteAdapter");
s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,8 @@ void Touchscreen::Motor::SetState(ControlState state)

void Touchscreen::Motor::Rumble(int padID, double state)
{
JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
JNIEnv* env = IDCache::GetEnvForThread();
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetDoRumble(), padID, state);
IDCache::GetJavaVM()->DetachCurrentThread();
}
} // namespace Android
} // namespace ciface
17 changes: 4 additions & 13 deletions Source/Core/InputCommon/GCAdapter_Android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ static void ScanThreadFunc()
Common::SetCurrentThreadName("GC Adapter Scanning Thread");
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread started");

JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
JNIEnv* env = IDCache::GetEnvForThread();

jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");

Expand All @@ -77,7 +76,6 @@ static void ScanThreadFunc()
Setup();
Common::SleepCurrentThread(1000);
}
IDCache::GetJavaVM()->DetachCurrentThread();

NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread stopped");
}
Expand All @@ -87,8 +85,7 @@ static void Write()
Common::SetCurrentThreadName("GC Adapter Write Thread");
NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread started");

JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
JNIEnv* env = IDCache::GetEnvForThread();
jmethodID output_func = env->GetStaticMethodID(s_adapter_class, "Output", "([B)I");

while (s_write_adapter_thread_running.IsSet())
Expand Down Expand Up @@ -118,8 +115,6 @@ static void Write()
Common::YieldCPU();
}

IDCache::GetJavaVM()->DetachCurrentThread();

NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread stopped");
}

Expand All @@ -129,8 +124,7 @@ static void Read()
NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread started");

bool first_read = true;
JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
JNIEnv* env = IDCache::GetEnvForThread();

jfieldID payload_field = env->GetStaticFieldID(s_adapter_class, "controller_payload", "[B");
jobject payload_object = env->GetStaticObjectField(s_adapter_class, payload_field);
Expand Down Expand Up @@ -184,8 +178,6 @@ static void Read()
s_fd = 0;
s_detected = false;

IDCache::GetJavaVM()->DetachCurrentThread();

NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread stopped");
}

Expand All @@ -202,8 +194,7 @@ void Init()
s_last_init = CoreTiming::GetTicks();
}

JNIEnv* env;
IDCache::GetJavaVM()->AttachCurrentThread(&env, NULL);
JNIEnv* env = IDCache::GetEnvForThread();

jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_GCAdapter");
s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
Expand Down

0 comments on commit 0dec8fe

Please sign in to comment.