Compare commits
1 Commits
component-
...
rh/infinit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccdb07eea5 |
@@ -151,29 +151,17 @@ export function flushSyncWorkOnLegacyRootsOnly() {
|
||||
flushSyncWorkAcrossRoots_impl(true);
|
||||
}
|
||||
|
||||
function flushSyncWorkAcrossRoots_impl(onlyLegacy: boolean) {
|
||||
if (isFlushingWork) {
|
||||
// Prevent reentrancy.
|
||||
// TODO: Is this overly defensive? The callers must check the execution
|
||||
// context first regardless.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mightHavePendingSyncWork) {
|
||||
// Fast path. There's no sync work to do.
|
||||
return;
|
||||
}
|
||||
|
||||
const workInProgressRoot = getWorkInProgressRoot();
|
||||
const workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes();
|
||||
|
||||
// There may or may not be synchronous work scheduled. Let's check.
|
||||
let didPerformSomeWork;
|
||||
export function _doFlushWork(
|
||||
firstRoot,
|
||||
workInProgressRoot,
|
||||
workInProgressRootRenderLanes,
|
||||
onlyLegacy,
|
||||
) {
|
||||
let didPerformSomeWork = false;
|
||||
let errors: Array<mixed> | null = null;
|
||||
isFlushingWork = true;
|
||||
do {
|
||||
didPerformSomeWork = false;
|
||||
let root = firstScheduledRoot;
|
||||
let root = firstRoot;
|
||||
while (root !== null) {
|
||||
if (onlyLegacy && root.tag !== LegacyRoot) {
|
||||
// Skip non-legacy roots.
|
||||
@@ -202,6 +190,33 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy: boolean) {
|
||||
root = root.next;
|
||||
}
|
||||
} while (didPerformSomeWork);
|
||||
|
||||
return errors;
|
||||
}
|
||||
function flushSyncWorkAcrossRoots_impl(onlyLegacy: boolean) {
|
||||
if (isFlushingWork) {
|
||||
// Prevent reentrancy.
|
||||
// TODO: Is this overly defensive? The callers must check the execution
|
||||
// context first regardless.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mightHavePendingSyncWork) {
|
||||
// Fast path. There's no sync work to do.
|
||||
return;
|
||||
}
|
||||
|
||||
const workInProgressRoot = getWorkInProgressRoot();
|
||||
const workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes();
|
||||
|
||||
// There may or may not be synchronous work scheduled. Let's check.
|
||||
isFlushingWork = true;
|
||||
const errors = _doFlushWork(
|
||||
firstScheduledRoot,
|
||||
workInProgressRoot,
|
||||
workInProgressRootRenderLanes,
|
||||
onlyLegacy,
|
||||
);
|
||||
isFlushingWork = false;
|
||||
|
||||
// If any errors were thrown, rethrow them right before exiting.
|
||||
|
||||
63
packages/react-reconciler/src/__tests__/ReactFiberRootScheduler-test.js
vendored
Normal file
63
packages/react-reconciler/src/__tests__/ReactFiberRootScheduler-test.js
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
let _doFlushWork;
|
||||
const shimHostConfigPath = 'react-reconciler/src/ReactFiberConfig';
|
||||
|
||||
jest.mock(shimHostConfigPath, () => {
|
||||
return jest.requireActual(
|
||||
'react-dom-bindings/src/client/ReactFiberConfigDOM.js',
|
||||
);
|
||||
});
|
||||
beforeAll(() => {
|
||||
_doFlushWork = require('../ReactFiberRootScheduler')._doFlushWork;
|
||||
});
|
||||
|
||||
test('does not hang', () => {
|
||||
const root = {
|
||||
tag: 1,
|
||||
pendingChildren: null,
|
||||
pingCache: {},
|
||||
finishedWork: null,
|
||||
timeoutHandle: -1,
|
||||
cancelPendingCommit: null,
|
||||
context: {},
|
||||
pendingContext: null,
|
||||
next: null,
|
||||
callbackNode: null,
|
||||
callbackPriority: 0,
|
||||
expirationTimes: [
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 278303.90000000596,
|
||||
278417.1999999881, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
],
|
||||
pendingLanes: 6176,
|
||||
suspendedLanes: 0,
|
||||
pingedLanes: 0,
|
||||
expiredLanes: 0,
|
||||
mutableReadLanes: 0,
|
||||
finishedLanes: 0,
|
||||
errorRecoveryDisabledLanes: 0,
|
||||
entangledLanes: 6144,
|
||||
entanglements: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6144, 6144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
],
|
||||
hiddenUpdates: [],
|
||||
identifierPrefix: '',
|
||||
pooledCache: null,
|
||||
pooledCacheLanes: 0,
|
||||
mutableSourceEagerHydrationData: null,
|
||||
hydrationCallbacks: {
|
||||
unstable_concurrentUpdatesByDefault: true,
|
||||
unstable_strictMode: true,
|
||||
},
|
||||
incompleteTransitions: {},
|
||||
effectDuration: 0,
|
||||
passiveEffectDuration: 0,
|
||||
memoizedUpdaters: {},
|
||||
pendingUpdatersLaneMap: [],
|
||||
_debugRootType: 'hydrateRoot()',
|
||||
};
|
||||
|
||||
expect(() => {
|
||||
_doFlushWork(root, root, 2, false);
|
||||
}).not.toThrow();
|
||||
});
|
||||
Reference in New Issue
Block a user