Increase the stack size for the React queue on older Android phones

Summary:
Older Android devices don't have a large stack by default and with about 16 levels of views the app will crash. Modern Android devices are fine so we can continue to use the system defaults while using a 2MB stack on older Android devices.
Closes https://github.com/facebook/react-native/pull/7416

Differential Revision: D3276805

Pulled By: astreet

fbshipit-source-id: a7b31a1be62e13f333148ca0908eb01a11aa4562
This commit is contained in:
Nikhilesh Sigatapu 2016-05-09 11:47:47 -07:00 committed by Facebook Github Bot 4
parent 963a53b1a7
commit d4f6f61a96
3 changed files with 43 additions and 10 deletions

View File

@ -131,7 +131,7 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
case MAIN_UI:
return createForMainThread(spec.getName(), exceptionHandler);
case NEW_BACKGROUND:
return startNewBackgroundThread(spec.getName(), exceptionHandler);
return startNewBackgroundThread(spec.getName(), spec.getStackSize(), exceptionHandler);
default:
throw new RuntimeException("Unknown thread type: " + spec.getThreadType());
}
@ -165,17 +165,27 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
return mqt;
}
/**
* Creates and starts a new MessageQueueThreadImpl encapsulating a new Thread with a new Looper
* running on it. Give it a name for easier debugging. When this method exits, the new
* MessageQueueThreadImpl is ready to receive events.
*/
public static MessageQueueThreadImpl startNewBackgroundThread(
final String name,
QueueThreadExceptionHandler exceptionHandler) {
return startNewBackgroundThread(
name,
MessageQueueThreadSpec.DEFAULT_STACK_SIZE_BYTES,
exceptionHandler);
}
/**
* Creates and starts a new MessageQueueThreadImpl encapsulating a new Thread with a new Looper
* running on it. Give it a name for easier debugging and optionally a suggested stack size.
* When this method exits, the new MessageQueueThreadImpl is ready to receive events.
*/
public static MessageQueueThreadImpl startNewBackgroundThread(
final String name,
long stackSize,
QueueThreadExceptionHandler exceptionHandler) {
final SimpleSettableFuture<Looper> looperFuture = new SimpleSettableFuture<>();
final SimpleSettableFuture<MessageQueueThread> mqtFuture = new SimpleSettableFuture<>();
Thread bgThread = new Thread(
Thread bgThread = new Thread(null,
new Runnable() {
@Override
public void run() {
@ -186,7 +196,7 @@ public class MessageQueueThreadImpl implements MessageQueueThread {
Looper.loop();
}
}, "mqt_" + name);
}, "mqt_" + name, stackSize);
bgThread.start();
Looper myLooper = looperFuture.getOrThrow();

View File

@ -17,6 +17,9 @@ public class MessageQueueThreadSpec {
private static final MessageQueueThreadSpec MAIN_UI_SPEC =
new MessageQueueThreadSpec(ThreadType.MAIN_UI, "main_ui");
// The Thread constructor interprets zero the same as not specifying a stack size
public static final long DEFAULT_STACK_SIZE_BYTES = 0;
protected static enum ThreadType {
MAIN_UI,
NEW_BACKGROUND,
@ -26,16 +29,26 @@ public class MessageQueueThreadSpec {
return new MessageQueueThreadSpec(ThreadType.NEW_BACKGROUND, name);
}
public static MessageQueueThreadSpec newBackgroundThreadSpec(String name, long stackSize) {
return new MessageQueueThreadSpec(ThreadType.NEW_BACKGROUND, name, stackSize);
}
public static MessageQueueThreadSpec mainThreadSpec() {
return MAIN_UI_SPEC;
}
private final ThreadType mThreadType;
private final String mName;
private final long mStackSize;
private MessageQueueThreadSpec(ThreadType threadType, String name) {
this(threadType, name, DEFAULT_STACK_SIZE_BYTES);
}
private MessageQueueThreadSpec(ThreadType threadType, String name, long stackSize) {
mThreadType = threadType;
mName = name;
mStackSize = stackSize;
}
public ThreadType getThreadType() {
@ -45,4 +58,8 @@ public class MessageQueueThreadSpec {
public String getName() {
return mName;
}
public long getStackSize() {
return mStackSize;
}
}

View File

@ -9,6 +9,8 @@
package com.facebook.react.bridge.queue;
import android.os.Build;
import javax.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
@ -21,6 +23,8 @@ import com.facebook.infer.annotation.Assertions;
*/
public class ReactQueueConfigurationSpec {
private static final long LEGACY_STACK_SIZE_BYTES = 2000000;
private final MessageQueueThreadSpec mNativeModulesQueueThreadSpec;
private final MessageQueueThreadSpec mJSQueueThreadSpec;
@ -44,10 +48,12 @@ public class ReactQueueConfigurationSpec {
}
public static ReactQueueConfigurationSpec createDefault() {
MessageQueueThreadSpec spec = Build.VERSION.SDK_INT < 21 ?
MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules", LEGACY_STACK_SIZE_BYTES) :
MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules");
return builder()
.setJSQueueThreadSpec(MessageQueueThreadSpec.newBackgroundThreadSpec("js"))
.setNativeModulesQueueThreadSpec(
MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules"))
.setNativeModulesQueueThreadSpec(spec)
.build();
}