Skip to content

Commit

Permalink
Enabled blocking access for animated queues under feature flag
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Andrei Shikov authored and facebook-github-bot committed Mar 10, 2022
1 parent 04acb1c commit b347c39
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rn_android_library(
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/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/annotations:annotations"),
react_native_target("java/com/facebook/react/views/view:view"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.facebook.react.bridge.UIManagerListener;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.ReactChoreographer;
Expand Down Expand Up @@ -108,20 +109,40 @@ public long getBatchNumber() {
private class ConcurrentOperationQueue {
private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
@Nullable private UIThreadOperation mPeekedOperation = null;
private boolean mSynchronizedAccess = false;

@AnyThread
boolean isEmpty() {
return mQueue.isEmpty();
}

void setSynchronizedAccess(boolean isSynchronizedAccess) {
mSynchronizedAccess = isSynchronizedAccess;
}

@AnyThread
void add(UIThreadOperation operation) {
mQueue.add(operation);
if (mSynchronizedAccess) {
synchronized (this) {
mQueue.add(operation);
}
} else {
mQueue.add(operation);
}
}

@UiThread
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) {
operation.execute(nodesManager);
}
Expand Down Expand Up @@ -210,6 +231,10 @@ protected void doFrameGuarded(final long frameTimeNanos) {
}
}
};

// If shipping this flag, make sure to migrate to non-concurrent queue for efficiency
mOperations.setSynchronizedAccess(ReactFeatureFlags.enableSynchronizationForAnimated);
mPreOperations.setSynchronizedAccess(ReactFeatureFlags.enableSynchronizationForAnimated);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public class ReactFeatureFlags {
/** Feature flag to configure eager attachment of the root view/initialisation of the JS code */
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;

/** Enables or disables MapBuffer Serialization */
Expand Down

0 comments on commit b347c39

Please sign in to comment.