From 25e8fbe8ffa1c91522e91819a781434093f8b759 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Wed, 9 Jun 2021 23:46:45 -0700 Subject: [PATCH] Ensure that EventEmitterWrapper is cleaned up as soon as a View is deleted Summary: In T92179998, there is a crash when an EventEmitterWrapper is deallocated after the JS VM is torn down, and the EventEmitterWrapper tries to free its JSI::Pointer reference (double-free). To make sure this happens less/not at all, free EventEmitterWrappers on ViewState when a view is deleted, instead of waiting for all of RN to be torn down. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D29020768 fbshipit-source-id: 9d72a23bc9966992ef56c1e3ee523405d4333194 --- .../react/fabric/mounting/SurfaceMountingManager.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java index 004af2f6471..650c5b91276 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java @@ -813,6 +813,14 @@ public class SurfaceMountingManager { viewState.mStateWrapper = null; } + // Destroy EventEmitterWrapper immediately instead of waiting for Java GC. + // Notably, this is also required to ensure that the EventEmitterWrapper is deallocated + // before the JS VM is deallocated, since it holds onto a JSI::Pointer. + if (viewState.mEventEmitter != null) { + viewState.mEventEmitter.destroy(); + viewState.mEventEmitter = null; + } + // For non-root views we notify viewmanager with {@link ViewManager#onDropInstance} ViewManager viewManager = viewState.mViewManager; if (!viewState.mIsRoot && viewManager != null) {