From 0a7a228fbb68d04e09748af642358b645721a2b8 Mon Sep 17 00:00:00 2001 From: Charles Dick Date: Tue, 3 May 2016 13:27:10 -0700 Subject: [PATCH] Fix crash in adsmanager login by nolonger assuming only one react context exists at once Reviewed By: lexs Differential Revision: D3252624 fb-gh-sync-id: e1d1c914be4e0caab953478f12441b440bd1f894 fbshipit-source-id: e1d1c914be4e0caab953478f12441b440bd1f894 --- .../devsupport/DevSupportManagerImpl.java | 15 ++++--- .../react/devsupport/JSCHeapCapture.java | 42 +++++++++++++------ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java index 84bef62fb..3925a0e82 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.LinkedHashMap; +import java.util.List; import java.util.Locale; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -310,12 +311,14 @@ public class DevSupportManagerImpl implements DevSupportManager { @Override public void onOptionSelected() { try { - String heapDumpPath = mApplicationContext.getCacheDir() + "/heapdump.json"; - JSCHeapCapture.captureHeap(heapDumpPath, 60000); - Toast.makeText( - mCurrentContext, - "Heap captured to " + heapDumpPath, - Toast.LENGTH_LONG).show(); + String heapDumpPath = mApplicationContext.getCacheDir().getPath(); + List captureFiles = JSCHeapCapture.captureHeap(heapDumpPath, 60000); + for (String captureFile : captureFiles) { + Toast.makeText( + mCurrentContext, + "Heap captured to " + captureFile, + Toast.LENGTH_LONG).show(); + } } catch (JSCHeapCapture.CaptureException e) { showNewJavaError(e.getMessage(), e); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java index b2bdc5e3d..4080b5d07 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCHeapCapture.java @@ -11,6 +11,11 @@ package com.facebook.react.devsupport; import javax.annotation.Nullable; +import java.io.File; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; @@ -33,28 +38,41 @@ public class JSCHeapCapture extends ReactContextBaseJavaModule { private int mOperationToken; private @Nullable String mOperationError; - private static @Nullable JSCHeapCapture sJSCHeapCapture = null; + private static final HashSet sRegisteredDumpers = new HashSet<>(); private static synchronized void registerHeapCapture(JSCHeapCapture dumper) { - if (sJSCHeapCapture != null) { + if (sRegisteredDumpers.contains(dumper)) { throw new RuntimeException( - "JSCHeapCapture already registered. Are you running more than one JSC?"); + "a JSCHeapCapture registered more than once"); } - sJSCHeapCapture = dumper; + sRegisteredDumpers.add(dumper); } private static synchronized void unregisterHeapCapture(JSCHeapCapture dumper) { - if (sJSCHeapCapture != dumper) { - throw new RuntimeException("Can't unregister JSCHeapCapture that is not registered."); - } - sJSCHeapCapture = null; + sRegisteredDumpers.remove(dumper); } - public static synchronized void captureHeap(String path, long timeout) throws CaptureException { - if (sJSCHeapCapture == null) { - throw new CaptureException("No JSC registered."); + public static synchronized List captureHeap(String path, long timeout) + throws CaptureException { + LinkedList captureFiles = new LinkedList<>(); + if (sRegisteredDumpers.isEmpty()) { + throw new CaptureException("No JSC registered"); } - sJSCHeapCapture.captureHeapHelper(path, timeout); + + int disambiguate = 0; + File f = new File(path + "/capture" + Integer.toString(disambiguate) + ".json"); + while (f.delete()) { + disambiguate++; + f = new File(path + "/capture" + Integer.toString(disambiguate) + ".json"); + } + + disambiguate = 0; + for (JSCHeapCapture dumper : sRegisteredDumpers) { + String file = path + "/capture" + Integer.toString(disambiguate) + ".json"; + dumper.captureHeapHelper(file, timeout); + captureFiles.add(file); + } + return captureFiles; } public JSCHeapCapture(ReactApplicationContext reactContext) {