Enabled blocking access for animated queues under feature flag

Summary:
Blocks on queue write/drain for Animated module under a feature flag to test whether it resolves race conditions.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D34752947

fbshipit-source-id: a1b1a286772d29a7a27b5e9c3f743cac84cc2bab
This commit is contained in:
Andrei Shikov 2022-03-10 04:30:37 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 04acb1cbc8
Коммит b347c3949f
3 изменённых файлов: 31 добавлений и 2 удалений

Просмотреть файл

@ -26,6 +26,7 @@ rn_android_library(
react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/common:common"),
react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/module/annotations:annotations"),
react_native_target("java/com/facebook/react/modules/core:core"), react_native_target("java/com/facebook/react/modules/core:core"),
react_native_target("java/com/facebook/react/config:config"),
react_native_target("java/com/facebook/react/uimanager:uimanager"), react_native_target("java/com/facebook/react/uimanager:uimanager"),
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"), react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
react_native_target("java/com/facebook/react/views/view:view"), react_native_target("java/com/facebook/react/views/view:view"),

Просмотреть файл

@ -24,6 +24,7 @@ import com.facebook.react.bridge.UIManager;
import com.facebook.react.bridge.UIManagerListener; import com.facebook.react.bridge.UIManagerListener;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.modules.core.ReactChoreographer;
@ -108,20 +109,40 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
private class ConcurrentOperationQueue { private class ConcurrentOperationQueue {
private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>(); private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
@Nullable private UIThreadOperation mPeekedOperation = null; @Nullable private UIThreadOperation mPeekedOperation = null;
private boolean mSynchronizedAccess = false;
@AnyThread @AnyThread
boolean isEmpty() { boolean isEmpty() {
return mQueue.isEmpty(); return mQueue.isEmpty();
} }
void setSynchronizedAccess(boolean isSynchronizedAccess) {
mSynchronizedAccess = isSynchronizedAccess;
}
@AnyThread @AnyThread
void add(UIThreadOperation operation) { void add(UIThreadOperation operation) {
mQueue.add(operation); if (mSynchronizedAccess) {
synchronized (this) {
mQueue.add(operation);
}
} else {
mQueue.add(operation);
}
} }
@UiThread @UiThread
void executeBatch(long maxBatchNumber, NativeAnimatedNodesManager nodesManager) { void executeBatch(long maxBatchNumber, NativeAnimatedNodesManager nodesManager) {
List<UIThreadOperation> operations = drainQueueIntoList(maxBatchNumber);
List<UIThreadOperation> operations;
if (mSynchronizedAccess) {
synchronized (this) {
operations = drainQueueIntoList(maxBatchNumber);
}
} else {
operations = drainQueueIntoList(maxBatchNumber);
}
for (UIThreadOperation operation : operations) { for (UIThreadOperation operation : operations) {
operation.execute(nodesManager); operation.execute(nodesManager);
} }
@ -210,6 +231,10 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
} }
} }
}; };
// If shipping this flag, make sure to migrate to non-concurrent queue for efficiency
mOperations.setSynchronizedAccess(ReactFeatureFlags.enableSynchronizationForAnimated);
mPreOperations.setSynchronizedAccess(ReactFeatureFlags.enableSynchronizationForAnimated);
} }
@Override @Override

Просмотреть файл

@ -71,6 +71,9 @@ public class ReactFeatureFlags {
/** Feature flag to configure eager attachment of the root view/initialisation of the JS code */ /** Feature flag to configure eager attachment of the root view/initialisation of the JS code */
public static boolean enableEagerRootViewAttachment = false; public static boolean enableEagerRootViewAttachment = false;
/** Feature flag to configure synchronized queue access for Animated module */
public static boolean enableSynchronizationForAnimated = false;
private static boolean mapBufferSerializationEnabled = false; private static boolean mapBufferSerializationEnabled = false;
/** Enables or disables MapBuffer Serialization */ /** Enables or disables MapBuffer Serialization */