Skip to content

Commit

Permalink
Fix NullPointerException caused by race condition in ReactInstanceMan…
Browse files Browse the repository at this point in the history
…ager.getViewManagerNames method

Summary:
This diff fixes a NullPointerException that is caused when the method ReactInstanceManager.getViewManagerNames is called at the same time ReactInstanceManager is being destroyed.

Following the stacktrace I noticed that this crash can only happen when RN was destroyed by another thread while this method was being executed

This diff fixes the NullPointerException, but it doesn't fix the root cause race condition that cuases this bug

changelog: [Android][Fixed] Fix NullPointerException caused by race condition in ReactInstanceManager.getViewManagerNames method

Reviewed By: JoshuaGross

Differential Revision: D29616401

fbshipit-source-id: 6ae8ecdd765d2fe3529fef3237f08b182d8ed243
  • Loading branch information
mdvacca authored and facebook-github-bot committed Jul 8, 2021
1 parent 8ed4068 commit fb386fc
Showing 1 changed file with 27 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -918,38 +918,40 @@ public List<ViewManager> getOrCreateViewManagers(

public @Nullable List<String> getViewManagerNames() {
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerNames");
if (mViewManagerNames == null) {
ReactApplicationContext context;
synchronized (mReactContextLock) {
context = (ReactApplicationContext) getCurrentReactContext();
if (context == null || !context.hasActiveReactInstance()) {
return null;
}
List<String> viewManagerNames = mViewManagerNames;
if (viewManagerNames != null) {
return viewManagerNames;
}
ReactApplicationContext context;
synchronized (mReactContextLock) {
context = (ReactApplicationContext) getCurrentReactContext();
if (context == null || !context.hasActiveReactInstance()) {
return null;
}
}

synchronized (mPackages) {
if (mViewManagerNames == null) {
Set<String> uniqueNames = new HashSet<>();
for (ReactPackage reactPackage : mPackages) {
SystraceMessage.beginSection(
TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerName")
.arg("Package", reactPackage.getClass().getSimpleName())
.flush();
if (reactPackage instanceof ViewManagerOnDemandReactPackage) {
List<String> names =
((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(context);
if (names != null) {
uniqueNames.addAll(names);
}
synchronized (mPackages) {
if (mViewManagerNames == null) {
Set<String> uniqueNames = new HashSet<>();
for (ReactPackage reactPackage : mPackages) {
SystraceMessage.beginSection(
TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerName")
.arg("Package", reactPackage.getClass().getSimpleName())
.flush();
if (reactPackage instanceof ViewManagerOnDemandReactPackage) {
List<String> names =
((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(context);
if (names != null) {
uniqueNames.addAll(names);
}
SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush();
}
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
mViewManagerNames = new ArrayList<>(uniqueNames);
SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush();
}
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
mViewManagerNames = new ArrayList<>(uniqueNames);
}
return mViewManagerNames;
}
return new ArrayList<>(mViewManagerNames);
}

/** Add a listener to be notified of react instance events. */
Expand Down

0 comments on commit fb386fc

Please sign in to comment.