-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
[ASTextNode2] Upgrade lock safety by protecting all ivars (including rarely-changed ones). #918
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work! A few small questions/opps then let's land.
Source/ASTextNode2.mm
Outdated
|
||
|
||
_shadowOpacity = shadowOpacity; | ||
|
||
[self setNeedsDisplay]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great place to use ASLockedSelfCompareAssign
!
Source/ASTextNode2.mm
Outdated
if (ASLockedSelfCompareAssignCopy(_truncationAttributedText, truncationAttributedText)) { | ||
ASLockScopeSelf(); | ||
if (!ASObjectIsEqual(_truncationAttributedText, truncationAttributedText)) { | ||
_truncationAttributedText = [truncationAttributedText copy]; | ||
[self _invalidateTruncationText]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change? Is it so that we now call _invalidateTruncationText
with the lock held?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, otherwise there is no transactional integrity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK in cases such as this (side effect keeps lock), we can use the non-locked compare-assign macros, like so:
ASLockScopeSelf();
if (ASCompareAssignCopy(_truncationAttributedText, truncationATtributedText)) {
[self _invalidateTruncationText];
}
I set it up to work either way!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! This is definitely an improvement.
I'm having trouble getting the minutes to circle back to this; will try, maybe this weekend.
Source/ASTextNode2.mm
Outdated
@@ -210,6 +212,7 @@ - (BOOL)supportsLayerBacking | |||
|
|||
- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset | |||
{ | |||
ASLockScopeSelf(); | |||
BOOL needsUpdate = !UIEdgeInsetsEqualToEdgeInsets(_textContainer.insets, textContainerInset); | |||
_textContainer.insets = textContainerInset; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good place for ASLockedSelfCompareAssignCustom
// If the text contains any links, return NO. | ||
NSAttributedString *attributedText = self.attributedText; | ||
NSAttributedString *attributedText = _attributedText; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we just took the lock, can we go back to using the ivar here?
Just to note: |
…rarely-changed ones). Although I don't know of any specific crashes caused by this, I think we should lock all properties by default. There are also some indications of premature optimization in keeping lock scope small, where it is actually important to have transactional integrity, and also where the ASDisplayNode base class is otherwise going to repeatedly re-lock the object anyway. I think this will remain pretty efficient, especially with os_unfair_lock enabled.
b94c2ba
to
f7ac965
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put the finishing touches on it (used the compare-assign macros with the locking fixes). So naturally, I approve! 💯 💯 🔥 😂😂😂
f7ac965
to
767dc5d
Compare
Although I don't know of any specific crashes caused by this, I think we should
lock all properties by default. There are also some indications of premature
optimization in keeping lock scope small, where it is actually important to
have transactional integrity, and also where the ASDisplayNode base class is
otherwise going to repeatedly re-lock the object anyway.
I think this will remain pretty efficient, especially with os_unfair_lock enabled.