[Libreoffice-commits] online.git: android/lib

Michael Meeks (via logerrit) logerrit at kemper.freedesktop.org
Fri Jan 3 12:23:27 UTC 2020


 android/lib/src/main/cpp/androidapp.cpp |   61 +++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 23 deletions(-)

New commits:
commit 3328b9e317509fce9461571b764758c824720c82
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Jan 3 10:21:10 2020 +0000
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Fri Jan 3 13:23:08 2020 +0100

    android: don't continually attach & detach the TLS JNIEnv.
    
    Change-Id: I76424e3af7b9d7fe4de486e7fa0903bb4f7dc17e
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/86166
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/android/lib/src/main/cpp/androidapp.cpp b/android/lib/src/main/cpp/androidapp.cpp
index 577df5a90..1e5a80686 100644
--- a/android/lib/src/main/cpp/androidapp.cpp
+++ b/android/lib/src/main/cpp/androidapp.cpp
@@ -56,7 +56,41 @@ JNI_OnLoad(JavaVM* vm, void*) {
     return JNI_VERSION_1_6;
 }
 
-static void send2JS(jclass loActivityClz, jobject loActivityObj, const std::vector<char>& buffer)
+// Exception safe JVM detach, JNIEnv is TLS for Java - so per-thread.
+class JNIThreadContext
+{
+    JNIEnv *_env;
+public:
+    JNIThreadContext()
+    {
+        assert(javaVM != nullptr);
+        jint res = javaVM->GetEnv((void**)&_env, JNI_VERSION_1_6);
+        if (res == JNI_EDETACHED) {
+            LOG_DBG("Attach worker thread");
+            res = javaVM->AttachCurrentThread(&_env, nullptr);
+            if (JNI_OK != res) {
+                LOG_DBG("Failed to AttachCurrentThread");
+            }
+        }
+        else if (res == JNI_EVERSION) {
+            LOG_DBG("GetEnv version not supported");
+            return;
+        }
+        else if (res != JNI_OK) {
+            LOG_DBG("GetEnv another error " << res);
+            return;
+        }
+    }
+
+    ~JNIThreadContext()
+    {
+        javaVM->DetachCurrentThread();
+    }
+
+    JNIEnv *getEnv() const { return _env; }
+};
+
+static void send2JS(const JNIThreadContext &jctx, jclass loActivityClz, jobject loActivityObj, const std::vector<char>& buffer)
 {
     LOG_DBG("Send to JS: " << LOOLProtocol::getAbbreviatedMessage(buffer.data(), buffer.size()));
 
@@ -114,33 +148,13 @@ static void send2JS(jclass loActivityClz, jobject loActivityObj, const std::vect
 
     LOG_DBG("Sending to JavaScript: " << subjs);
 
-    JNIEnv *env;
-    jint res = javaVM->GetEnv((void**)&env, JNI_VERSION_1_6);
-    if (res == JNI_EDETACHED) {
-        LOG_DBG("GetEnv need to attach thread");
-        res = javaVM->AttachCurrentThread(&env, nullptr);
-        if (JNI_OK != res) {
-            LOG_DBG("Failed to AttachCurrentThread");
-            return;
-        }
-    }
-    else if (res == JNI_EVERSION) {
-        LOG_DBG("GetEnv version not supported");
-        return;
-    }
-    else if (res != JNI_OK) {
-        LOG_DBG("GetEnv another error");
-        return;
-    }
-
+    JNIEnv *env = jctx.getEnv();
     jstring jstr = env->NewStringUTF(js.c_str());
     jmethodID callFakeWebsocket = env->GetMethodID(loActivityClz, "callFakeWebsocketOnMessage", "(Ljava/lang/String;)V");
     env->CallVoidMethod(loActivityObj, callFakeWebsocket, jstr);
 
     if (env->ExceptionCheck())
         env->ExceptionDescribe();
-
-    javaVM->DetachCurrentThread();
 }
 
 /// Close the document.
@@ -191,6 +205,7 @@ Java_org_libreoffice_androidlib_LOActivity_postMobileMessageNative(JNIEnv *env,
             std::thread([loActivityClz, loActivityObj, currentFakeClientFd]
                         {
                             Util::setThreadName("app2js");
+                            JNIThreadContext ctx;
                             while (true)
                             {
                                struct pollfd pollfd[2];
@@ -228,7 +243,7 @@ Java_org_libreoffice_androidlib_LOActivity_postMobileMessageNative(JNIEnv *env,
                                            return;
                                        std::vector<char> buf(n);
                                        n = fakeSocketRead(currentFakeClientFd, buf.data(), n);
-                                       send2JS(loActivityClz, loActivityObj, buf);
+                                       send2JS(ctx, loActivityClz, loActivityObj, buf);
                                    }
                                }
                                else


More information about the Libreoffice-commits mailing list