mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-09 22:43:10 +08:00
WebWorkers: Allow native modules to be notified when executors are unregistered
Summary: This will allow them to clean up resources when a web worker goes away. Reviewed By: mhorowitz, lexs Differential Revision: D2994721 fb-gh-sync-id: c7ca1afc7290e85038cf692a139f6478dba0ef61 shipit-source-id: c7ca1afc7290e85038cf692a139f6478dba0ef61
This commit is contained in:
committed by
Facebook Github Bot 3
parent
1bab7c5182
commit
6d5f9ddfff
@@ -222,8 +222,10 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
Systrace.unregisterListener(mTraceListener);
|
||||
|
||||
synchronouslyDisposeBridgeOnJSThread();
|
||||
mReactQueueConfiguration.destroy();
|
||||
}
|
||||
|
||||
mReactQueueConfiguration.destroy();
|
||||
|
||||
boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0);
|
||||
if (!wasIdle && !mBridgeIdleListeners.isEmpty()) {
|
||||
for (NotThreadSafeBridgeIdleDebugListener listener : mBridgeIdleListeners) {
|
||||
@@ -293,12 +295,12 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
@Override
|
||||
public void handleMemoryPressure(final MemoryPressure level) {
|
||||
mReactQueueConfiguration.getJSQueueThread().runOnQueue(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Assertions.assertNotNull(mBridge).handleMemoryPressure(level);
|
||||
}
|
||||
});
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Assertions.assertNotNull(mBridge).handleMemoryPressure(level);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,12 +401,14 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
public void call(ExecutorToken executorToken, int moduleId, int methodId, ReadableNativeArray parameters) {
|
||||
mReactQueueConfiguration.getNativeModulesQueueThread().assertIsOnThread();
|
||||
|
||||
// Suppress any callbacks if destroyed - will only lead to sadness.
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
synchronized (mTeardownLock) {
|
||||
// Suppress any callbacks if destroyed - will only lead to sadness.
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
mJavaRegistry.call(CatalystInstanceImpl.this, executorToken, moduleId, methodId, parameters);
|
||||
mJavaRegistry.call(CatalystInstanceImpl.this, executorToken, moduleId, methodId, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -415,17 +419,38 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
// native modules could be in a bad state so we don't want to call anything on them. We
|
||||
// still want to trigger the debug listener since it allows instrumentation tests to end and
|
||||
// check their assertions without waiting for a timeout.
|
||||
if (!mDestroyed) {
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "onBatchComplete");
|
||||
try {
|
||||
mJavaRegistry.onBatchComplete();
|
||||
} finally {
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
synchronized (mTeardownLock) {
|
||||
if (!mDestroyed) {
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "onBatchComplete");
|
||||
try {
|
||||
mJavaRegistry.onBatchComplete();
|
||||
} finally {
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decrementPendingJSCalls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExecutorUnregistered(ExecutorToken executorToken) {
|
||||
mReactQueueConfiguration.getNativeModulesQueueThread().assertIsOnThread();
|
||||
|
||||
// Since onCatalystInstanceDestroy happens on the UI thread, we don't want to also execute
|
||||
// this callback on the native modules thread at the same time. Longer term, onCatalystInstanceDestroy
|
||||
// should probably be executed on the native modules thread as well instead.
|
||||
synchronized (mTeardownLock) {
|
||||
if (!mDestroyed) {
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "onExecutorUnregistered");
|
||||
try {
|
||||
mJavaRegistry.onExecutorUnregistered(executorToken);
|
||||
} finally {
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NativeExceptionHandler implements QueueThreadExceptionHandler {
|
||||
|
||||
@@ -30,6 +30,7 @@ public class NativeModuleRegistry {
|
||||
private final List<ModuleDefinition> mModuleTable;
|
||||
private final Map<Class<? extends NativeModule>, NativeModule> mModuleInstances;
|
||||
private final ArrayList<OnBatchCompleteListener> mBatchCompleteListenerModules;
|
||||
private final ArrayList<OnExecutorUnregisteredListener> mOnExecutorUnregisteredListenerModules;
|
||||
|
||||
private NativeModuleRegistry(
|
||||
List<ModuleDefinition> moduleTable,
|
||||
@@ -37,12 +38,16 @@ public class NativeModuleRegistry {
|
||||
mModuleTable = moduleTable;
|
||||
mModuleInstances = moduleInstances;
|
||||
|
||||
mBatchCompleteListenerModules = new ArrayList<OnBatchCompleteListener>(mModuleTable.size());
|
||||
mBatchCompleteListenerModules = new ArrayList<>(mModuleTable.size());
|
||||
mOnExecutorUnregisteredListenerModules = new ArrayList<>(mModuleTable.size());
|
||||
for (int i = 0; i < mModuleTable.size(); i++) {
|
||||
ModuleDefinition definition = mModuleTable.get(i);
|
||||
if (definition.target instanceof OnBatchCompleteListener) {
|
||||
mBatchCompleteListenerModules.add((OnBatchCompleteListener) definition.target);
|
||||
}
|
||||
if (definition.target instanceof OnExecutorUnregisteredListener) {
|
||||
mOnExecutorUnregisteredListenerModules.add((OnExecutorUnregisteredListener) definition.target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +140,12 @@ public class NativeModuleRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public void onExecutorUnregistered(ExecutorToken executorToken) {
|
||||
for (int i = 0; i < mOnExecutorUnregisteredListenerModules.size(); i++) {
|
||||
mOnExecutorUnregisteredListenerModules.get(i).onExecutorDestroyed(executorToken);
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends NativeModule> T getModule(Class<T> moduleInterface) {
|
||||
return (T) Assertions.assertNotNull(mModuleInstances.get(moduleInterface));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
/**
|
||||
* Interface for a module that will be notified when JS executors have been unregistered from the bridge.
|
||||
* Note that this will NOT notify listeners about the main executor being destroyed: use
|
||||
* {@link NativeModule#onCatalystInstanceDestroy()} for that. Once a module has received a
|
||||
* {@link NativeModule#onCatalystInstanceDestroy()} call, it will not receive any onExecutorUnregistered
|
||||
* calls.
|
||||
*/
|
||||
public interface OnExecutorUnregisteredListener {
|
||||
|
||||
void onExecutorDestroyed(ExecutorToken executorToken);
|
||||
}
|
||||
@@ -19,4 +19,7 @@ public interface ReactCallback {
|
||||
|
||||
@DoNotStrip
|
||||
void onBatchComplete();
|
||||
|
||||
@DoNotStrip
|
||||
void onExecutorUnregistered(ExecutorToken executorToken);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user