summaryrefslogtreecommitdiff
path: root/Lib/java
diff options
context:
space:
mode:
authorJoachim Kuebart <joachim.kuebart@gmail.com>2021-08-13 17:26:57 +0200
committerJoachim Kuebart <joachim.kuebart@gmail.com>2022-05-23 17:17:18 +0200
commitb58c554cdee28b1c79ad8a097da63751a237faee (patch)
treec8846538bc9880c3c6534db6b384c9b14dd5d221 /Lib/java
parent1ad77e8c9b955dfbf4c7b48890dcf49278b1e422 (diff)
downloadswig-b58c554cdee28b1c79ad8a097da63751a237faee.tar.gz
Java: Option to detach from the JVM in the thread destructor.
Diffstat (limited to 'Lib/java')
-rw-r--r--Lib/java/director.swg28
1 files changed, 27 insertions, 1 deletions
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index e911a3da7..f7c4f2d8a 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -51,6 +51,22 @@ SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
#endif
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+#include <pthread.h>
+namespace {
+
+ void detach(void* jvm) {
+ static_cast<JavaVM*>(jvm)->DetachCurrentThread();
+ }
+
+ pthread_key_t detachKey;
+ void makeDetachKey() {
+ pthread_key_create(&detachKey, detach);
+ }
+
+}
+#endif
+
namespace Swig {
/* Java object wrapper */
@@ -201,9 +217,19 @@ namespace Swig {
#else
director_->swig_jvm_->AttachCurrentThread(jenv, &args);
#endif
+
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+ // At least on Android 6, detaching after every call causes a memory leak.
+ // Instead, register a thread desructor and detach only when the thread ends.
+ // See https://developer.android.com/training/articles/perf-jni#threads
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+ pthread_once(&once, makeDetachKey);
+ pthread_setspecific(detachKey, director->swig_jvm_);
+#endif
}
~JNIEnvWrapper() {
-#if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
+#if !defined(SWIG_JAVA_DETACH_ON_THREAD_END) && !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
// Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
// However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
if (env_status == JNI_EDETACHED)