@onekeyfe/react-native-background-thread 1.1.58 → 1.1.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -99,14 +99,21 @@ Java_com_backgroundthread_BackgroundThreadManager_nativeInstallSharedBridge(
|
|
|
99
99
|
|
|
100
100
|
SharedStore::install(*rt);
|
|
101
101
|
|
|
102
|
-
// Create executor that schedules work on this runtime's JS thread via Kotlin
|
|
103
|
-
|
|
102
|
+
// Create executor that schedules work on this runtime's JS thread via Kotlin.
|
|
103
|
+
// Wrap GlobalRef in shared_ptr so it is automatically released when all
|
|
104
|
+
// copies of the executor lambda are destroyed (e.g. on runtime reload).
|
|
105
|
+
auto ref = std::shared_ptr<_jobject>(env->NewGlobalRef(thiz), [](jobject r) {
|
|
106
|
+
if (r) {
|
|
107
|
+
JNIEnv *e = getJNIEnv();
|
|
108
|
+
if (e) e->DeleteGlobalRef(r);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
104
111
|
bool capturedIsMain = static_cast<bool>(isMain);
|
|
105
112
|
|
|
106
113
|
RPCRuntimeExecutor executor = [ref, capturedIsMain](std::function<void(jsi::Runtime &)> work) {
|
|
107
114
|
JNIEnv *env = getJNIEnv();
|
|
108
115
|
if (!env || !ref) {
|
|
109
|
-
LOGE("executor: env=%p, ref=%p — aborting", env, ref);
|
|
116
|
+
LOGE("executor: env=%p, ref=%p — aborting", env, ref.get());
|
|
110
117
|
return;
|
|
111
118
|
}
|
|
112
119
|
|
|
@@ -117,11 +124,11 @@ Java_com_backgroundthread_BackgroundThreadManager_nativeInstallSharedBridge(
|
|
|
117
124
|
gPendingWork[workId] = std::move(work);
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
jclass cls = env->GetObjectClass(ref);
|
|
127
|
+
jclass cls = env->GetObjectClass(ref.get());
|
|
121
128
|
jmethodID mid = env->GetMethodID(cls, "scheduleOnJSThread", "(ZJ)V");
|
|
122
129
|
if (mid) {
|
|
123
130
|
LOGI("executor: calling scheduleOnJSThread(isMain=%d, workId=%ld)", capturedIsMain, (long)workId);
|
|
124
|
-
env->CallVoidMethod(ref, mid, static_cast<jboolean>(capturedIsMain), static_cast<jlong>(workId));
|
|
131
|
+
env->CallVoidMethod(ref.get(), mid, static_cast<jboolean>(capturedIsMain), static_cast<jlong>(workId));
|
|
125
132
|
if (env->ExceptionCheck()) {
|
|
126
133
|
LOGE("executor: JNI exception after scheduleOnJSThread");
|
|
127
134
|
env->ExceptionDescribe();
|
|
@@ -217,6 +224,7 @@ Java_com_backgroundthread_BackgroundThreadManager_nativeDestroy(
|
|
|
217
224
|
JNIEnv *env, jobject thiz) {
|
|
218
225
|
|
|
219
226
|
SharedRPC::reset();
|
|
227
|
+
SharedStore::reset();
|
|
220
228
|
|
|
221
229
|
LOGI("Native resources cleaned up");
|
|
222
230
|
}
|
package/cpp/SharedRPC.cpp
CHANGED
|
@@ -46,6 +46,13 @@ void SharedRPC::install(jsi::Runtime &rt, RPCRuntimeExecutor executor,
|
|
|
46
46
|
void SharedRPC::reset() {
|
|
47
47
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
48
48
|
slots_.clear();
|
|
49
|
+
// Intentionally leak jsi::Function callbacks to avoid destroying them on the
|
|
50
|
+
// wrong thread (same rationale as the leak in install() for reload scenarios).
|
|
51
|
+
for (auto &listener : listeners_) {
|
|
52
|
+
if (listener.callback) {
|
|
53
|
+
new std::shared_ptr<jsi::Function>(std::move(listener.callback));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
49
56
|
listeners_.clear();
|
|
50
57
|
}
|
|
51
58
|
|