Skip to content

Commit 1dbc38a

Browse files
dattc2facebook-github-bot
authored andcommitted
make yoga threadsafe (#852)
Summary: Continuing facebook/yoga#791 nokia6686 is a former member of our team, so we are trying to pick up what he left and carry out the pull request. # Solution Improved from previous solution with jpap's suggestions. 2. Passing ```gDepth``` and ```gCurrentGenerationCount``` (renamed to **_depth_** and **_generationCount_** respectively) between function calls that stem from ```YGNodeCalculateLayout```. In ```YGNodeCalculateLayout```, pass ```depth``` as value 0, to indicate the root depth. Pull Request resolved: facebook/yoga#852 Reviewed By: SidharthGuglani Differential Revision: D15537450 Pulled By: davidaurelio fbshipit-source-id: 338f51383591ba27702ebe759f6c47c2dede3530
1 parent 3c41e73 commit 1dbc38a

1 file changed

Lines changed: 78 additions & 37 deletions

File tree

ReactCommon/yoga/yoga/Yoga.cpp

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,9 @@ bool YGLayoutNodeInternal(
953953
const char* reason,
954954
const YGConfigRef config,
955955
YGMarkerLayoutData& layoutMarkerData,
956-
void* const layoutContext);
956+
void* const layoutContext,
957+
const uint32_t depth,
958+
const uint32_t generationCount);
957959

958960
#ifdef DEBUG
959961
static void YGNodePrintInternal(
@@ -1197,7 +1199,9 @@ static void YGNodeComputeFlexBasisForChild(
11971199
const YGDirection direction,
11981200
const YGConfigRef config,
11991201
YGMarkerLayoutData& layoutMarkerData,
1200-
void* const layoutContext) {
1202+
void* const layoutContext,
1203+
const uint32_t depth,
1204+
const uint32_t generationCount) {
12011205
const YGFlexDirection mainAxis =
12021206
YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
12031207
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
@@ -1220,8 +1224,7 @@ static void YGNodeComputeFlexBasisForChild(
12201224
if (child->getLayout().computedFlexBasis.isUndefined() ||
12211225
(YGConfigIsExperimentalFeatureEnabled(
12221226
child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
1223-
child->getLayout().computedFlexBasisGeneration !=
1224-
gCurrentGenerationCount)) {
1227+
child->getLayout().computedFlexBasisGeneration != generationCount)) {
12251228
const YGFloatOptional paddingAndBorder = YGFloatOptional(
12261229
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
12271230
child->setLayoutComputedFlexBasis(
@@ -1372,13 +1375,15 @@ static void YGNodeComputeFlexBasisForChild(
13721375
"measure",
13731376
config,
13741377
layoutMarkerData,
1375-
layoutContext);
1378+
layoutContext,
1379+
depth,
1380+
generationCount);
13761381

13771382
child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax(
13781383
child->getLayout().measuredDimensions[dim[mainAxis]],
13791384
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth))));
13801385
}
1381-
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount);
1386+
child->setLayoutComputedFlexBasisGeneration(generationCount);
13821387
}
13831388

13841389
static void YGNodeAbsoluteLayoutChild(
@@ -1390,7 +1395,9 @@ static void YGNodeAbsoluteLayoutChild(
13901395
const YGDirection direction,
13911396
const YGConfigRef config,
13921397
YGMarkerLayoutData& layoutMarkerData,
1393-
void* const layoutContext) {
1398+
void* const layoutContext,
1399+
const uint32_t depth,
1400+
const uint32_t generationCount) {
13941401
const YGFlexDirection mainAxis =
13951402
YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
13961403
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
@@ -1496,7 +1503,9 @@ static void YGNodeAbsoluteLayoutChild(
14961503
"abs-measure",
14971504
config,
14981505
layoutMarkerData,
1499-
layoutContext);
1506+
layoutContext,
1507+
depth,
1508+
generationCount);
15001509
childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] +
15011510
child->getMarginForAxis(YGFlexDirectionRow, width).unwrap();
15021511
childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] +
@@ -1516,7 +1525,9 @@ static void YGNodeAbsoluteLayoutChild(
15161525
"abs-layout",
15171526
config,
15181527
layoutMarkerData,
1519-
layoutContext);
1528+
layoutContext,
1529+
depth,
1530+
generationCount);
15201531

15211532
if (child->isTrailingPosDefined(mainAxis) &&
15221533
!child->isLeadingPositionDefined(mainAxis)) {
@@ -1844,7 +1855,9 @@ static float YGNodeComputeFlexBasisForChildren(
18441855
const YGConfigRef config,
18451856
bool performLayout,
18461857
YGMarkerLayoutData& layoutMarkerData,
1847-
void* const layoutContext) {
1858+
void* const layoutContext,
1859+
const uint32_t depth,
1860+
const uint32_t generationCount) {
18481861
float totalOuterFlexBasis = 0.0f;
18491862
YGNodeRef singleFlexChild = nullptr;
18501863
YGVector children = node->getChildren();
@@ -1895,7 +1908,7 @@ static float YGNodeComputeFlexBasisForChildren(
18951908
continue;
18961909
}
18971910
if (child == singleFlexChild) {
1898-
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount);
1911+
child->setLayoutComputedFlexBasisGeneration(generationCount);
18991912
child->setLayoutComputedFlexBasis(YGFloatOptional(0));
19001913
} else {
19011914
YGNodeComputeFlexBasisForChild(
@@ -1910,7 +1923,9 @@ static float YGNodeComputeFlexBasisForChildren(
19101923
direction,
19111924
config,
19121925
layoutMarkerData,
1913-
layoutContext);
1926+
layoutContext,
1927+
depth,
1928+
generationCount);
19141929
}
19151930

19161931
totalOuterFlexBasis +=
@@ -2024,7 +2039,9 @@ static float YGDistributeFreeSpaceSecondPass(
20242039
const bool performLayout,
20252040
const YGConfigRef config,
20262041
YGMarkerLayoutData& layoutMarkerData,
2027-
void* const layoutContext) {
2042+
void* const layoutContext,
2043+
const uint32_t depth,
2044+
const uint32_t generationCount) {
20282045
float childFlexBasis = 0;
20292046
float flexShrinkScaledFactor = 0;
20302047
float flexGrowFactor = 0;
@@ -2190,7 +2207,9 @@ static float YGDistributeFreeSpaceSecondPass(
21902207
"flex",
21912208
config,
21922209
layoutMarkerData,
2193-
layoutContext);
2210+
layoutContext,
2211+
depth,
2212+
generationCount);
21942213
node->setLayoutHadOverflow(
21952214
node->getLayout().hadOverflow |
21962215
currentRelativeChild->getLayout().hadOverflow);
@@ -2321,7 +2340,9 @@ static void YGResolveFlexibleLength(
23212340
const bool performLayout,
23222341
const YGConfigRef config,
23232342
YGMarkerLayoutData& layoutMarkerData,
2324-
void* const layoutContext) {
2343+
void* const layoutContext,
2344+
const uint32_t depth,
2345+
const uint32_t generationCount) {
23252346
const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace;
23262347
// First pass: detect the flex items whose min/max constraints trigger
23272348
YGDistributeFreeSpaceFirstPass(
@@ -2347,7 +2368,9 @@ static void YGResolveFlexibleLength(
23472368
performLayout,
23482369
config,
23492370
layoutMarkerData,
2350-
layoutContext);
2371+
layoutContext,
2372+
depth,
2373+
generationCount);
23512374

23522375
collectedFlexItemsValues.remainingFreeSpace =
23532376
originalFreeSpace - distributedFreeSpace;
@@ -2647,7 +2670,9 @@ static void YGNodelayoutImpl(
26472670
const bool performLayout,
26482671
const YGConfigRef config,
26492672
YGMarkerLayoutData& layoutMarkerData,
2650-
void* const layoutContext) {
2673+
void* const layoutContext,
2674+
const uint32_t depth,
2675+
const uint32_t generationCount) {
26512676
YGAssertWithNode(
26522677
node,
26532678
YGFloatIsUndefined(availableWidth)
@@ -2828,7 +2853,9 @@ static void YGNodelayoutImpl(
28282853
config,
28292854
performLayout,
28302855
layoutMarkerData,
2831-
layoutContext);
2856+
layoutContext,
2857+
depth,
2858+
generationCount);
28322859

28332860
const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined
28342861
? false
@@ -2936,7 +2963,9 @@ static void YGNodelayoutImpl(
29362963
performLayout,
29372964
config,
29382965
layoutMarkerData,
2939-
layoutContext);
2966+
layoutContext,
2967+
depth,
2968+
generationCount);
29402969
}
29412970

29422971
node->setLayoutHadOverflow(
@@ -3110,7 +3139,9 @@ static void YGNodelayoutImpl(
31103139
"stretch",
31113140
config,
31123141
layoutMarkerData,
3113-
layoutContext);
3142+
layoutContext,
3143+
depth,
3144+
generationCount);
31143145
}
31153146
} else {
31163147
const float remainingCrossDim = containerCrossAxis -
@@ -3318,7 +3349,9 @@ static void YGNodelayoutImpl(
33183349
"multiline-stretch",
33193350
config,
33203351
layoutMarkerData,
3321-
layoutContext);
3352+
layoutContext,
3353+
depth,
3354+
generationCount);
33223355
}
33233356
}
33243357
break;
@@ -3458,7 +3491,9 @@ static void YGNodelayoutImpl(
34583491
direction,
34593492
config,
34603493
layoutMarkerData,
3461-
layoutContext);
3494+
layoutContext,
3495+
depth,
3496+
generationCount);
34623497
}
34633498

34643499
// STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
@@ -3486,7 +3521,6 @@ static void YGNodelayoutImpl(
34863521
}
34873522
}
34883523

3489-
uint32_t gDepth = 0;
34903524
bool gPrintChanges = false;
34913525
bool gPrintSkips = false;
34923526

@@ -3692,13 +3726,15 @@ bool YGLayoutNodeInternal(
36923726
const char* reason,
36933727
const YGConfigRef config,
36943728
YGMarkerLayoutData& layoutMarkerData,
3695-
void* const layoutContext) {
3729+
void* const layoutContext,
3730+
uint32_t depth,
3731+
const uint32_t generationCount) {
36963732
YGLayout* layout = &node->getLayout();
36973733

3698-
gDepth++;
3734+
depth++;
36993735

37003736
const bool needToVisitNode =
3701-
(node->isDirty() && layout->generationCount != gCurrentGenerationCount) ||
3737+
(node->isDirty() && layout->generationCount != generationCount) ||
37023738
layout->lastOwnerDirection != ownerDirection;
37033739

37043740
if (needToVisitNode) {
@@ -3800,8 +3836,8 @@ bool YGLayoutNodeInternal(
38003836
YGLogLevelVerbose,
38013837
nullptr,
38023838
"%s%d.{[skipped] ",
3803-
YGSpacer(gDepth),
3804-
gDepth);
3839+
YGSpacer(depth),
3840+
depth);
38053841
node->print(layoutContext);
38063842
Log::log(
38073843
node,
@@ -3823,8 +3859,8 @@ bool YGLayoutNodeInternal(
38233859
YGLogLevelVerbose,
38243860
nullptr,
38253861
"%s%d.{%s",
3826-
YGSpacer(gDepth),
3827-
gDepth,
3862+
YGSpacer(depth),
3863+
depth,
38283864
needToVisitNode ? "*" : "");
38293865
node->print(layoutContext);
38303866
Log::log(
@@ -3851,16 +3887,18 @@ bool YGLayoutNodeInternal(
38513887
performLayout,
38523888
config,
38533889
layoutMarkerData,
3854-
layoutContext);
3890+
layoutContext,
3891+
depth,
3892+
generationCount);
38553893

38563894
if (gPrintChanges) {
38573895
Log::log(
38583896
node,
38593897
YGLogLevelVerbose,
38603898
nullptr,
38613899
"%s%d.}%s",
3862-
YGSpacer(gDepth),
3863-
gDepth,
3900+
YGSpacer(depth),
3901+
depth,
38643902
needToVisitNode ? "*" : "");
38653903
node->print(layoutContext);
38663904
Log::log(
@@ -3924,8 +3962,7 @@ bool YGLayoutNodeInternal(
39243962
node->setDirty(false);
39253963
}
39263964

3927-
gDepth--;
3928-
layout->generationCount = gCurrentGenerationCount;
3965+
layout->generationCount = generationCount;
39293966

39303967
#ifdef YG_ENABLE_EVENTS
39313968
LayoutType layoutType;
@@ -4110,7 +4147,9 @@ void YGNodeCalculateLayoutWithContext(
41104147
"initial",
41114148
node->getConfig(),
41124149
marker.data,
4113-
layoutContext)) {
4150+
layoutContext,
4151+
0, // tree root
4152+
gCurrentGenerationCount)) {
41144153
node->setPosition(
41154154
node->getLayout().direction, ownerWidth, ownerHeight, ownerWidth);
41164155
YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f);
@@ -4162,7 +4201,9 @@ void YGNodeCalculateLayoutWithContext(
41624201
"initial",
41634202
nodeWithoutLegacyFlag->getConfig(),
41644203
layoutMarkerData,
4165-
layoutContext)) {
4204+
layoutContext,
4205+
0, // tree root
4206+
gCurrentGenerationCount)) {
41664207
nodeWithoutLegacyFlag->setPosition(
41674208
nodeWithoutLegacyFlag->getLayout().direction,
41684209
ownerWidth,

0 commit comments

Comments
 (0)