Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ASImageNode] Fix a threading issue which can cause a display completion block to never be executed #1148

Merged

Conversation

nguyenhuy
Copy link
Member

@nguyenhuy nguyenhuy commented Sep 28, 2018

  • Clear _displayCompletionBlock while we still have the node's instance lock. Because it may not be the same block by the time the lock is reacquired. In other words, it can happen that another thread sets a new display block after this thread releases the lock but before it reacquires it. And we don't want to clear out the new block.
  • Reduce a lock/unlock pair which should help perf a tiny bit.

Copy link
Contributor

@maicki maicki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@appleguy appleguy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to merge this, nice fix! Comments are non-blocking / optional observations.

if (shouldPerformDisplayCompletionBlock) {
_displayCompletionBlock = nil;
}

BOOL hasDebugLabel = (_debugLabelNode != nil);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since many of the calls in the debug label section require the lock anyway (like self.bounds), should we just continue holding the lock until after that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a comment below stating that we don't care about locking in the debug section. I don't remember the reasoning behind that (locking violation somehow?), but let's revisit it in another PR.

CHANGELOG.md Outdated
@@ -57,6 +57,7 @@
- Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157)
- Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki)
- [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166)
- [ASImageNode] Fix a threading issue which can cause a display completion block to never be executed. [Huy Nguyen](https://github.com/nguyenhuy) [#1148](https://github.com/TextureGroup/Texture/pull/1148)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the header file, it isn't too clear that calling the method multiple times will overwrite the previous block without calling it. In order to guarantee balanced calls, we'd probably need to track them with an array.

This seems like an increasingly common case in the framework (even interfaceStateDelegates now), so it might be worth creating a helper class like ASBlockList / ASBlockQueue to manage efficiently. Not important right now, just an idea.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that it'd be nice to have track all blocks in an array.

Copy link
Member

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@nguyenhuy nguyenhuy force-pushed the HN-Fix-Display-Completion-Block branch from 3494455 to ce4bb1c Compare November 4, 2018 19:58
…ode's instance lock

- Because it may not be the same block by the time the lock is reacquired. In other words, it can happen that another thread sets a new display block after this thread releases the lock but before it reacquires it. And we don't want to clear out the new block.
- Reduce a lock/unlock pair which should help perf a tiny bit.
@nguyenhuy nguyenhuy force-pushed the HN-Fix-Display-Completion-Block branch from ce4bb1c to 3a35a9a Compare November 4, 2018 19:58
@ghost
Copy link

ghost commented Nov 4, 2018

🚫 CI failed with log

@ghost
Copy link

ghost commented Nov 4, 2018

🚫 CI failed with log

@ghost
Copy link

ghost commented Nov 4, 2018

1 Warning
⚠️ Any source code changes should have an entry in CHANGELOG.md or have #trivial in their title.

Generated by 🚫 Danger

@nguyenhuy nguyenhuy changed the title [ASImageNode] Clear _displayCompletionBlock while we still have the node's instance lock [ASImageNode] Fix a threading issue which can cause a display completion block to never be executed Nov 5, 2018
@nguyenhuy nguyenhuy merged commit e745ade into TextureGroup:master Nov 5, 2018
mikezucc pushed a commit to mikezucc/Texture that referenced this pull request Nov 7, 2018
…tion block to never be executed (TextureGroup#1148)

- Clear _displayCompletionBlock while we still have the node's instance lock. Because it may not be the same block by the time the lock is reacquired. In other words, it can happen that another thread sets a new display block after this thread releases the lock but before it reacquires it. And we don't want to clear out the new block.
- Reduce a lock/unlock pair which should help perf a tiny bit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants