-
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
Fix Text Node Thread Sanitizer Warning #830
Conversation
Problem reported in this issue #552 |
Source/ASTextNode.mm
Outdated
@@ -85,8 +88,13 @@ - (BOOL)isEqual:(ASTextNodeRendererKey *)object | |||
if (self == object) { | |||
return YES; | |||
} | |||
|
|||
// Lock both objects, avoiding deadlock. | |||
std::lock(_m, object->_m); |
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.
Unrelated to you changes, should there be class checks in here? It may not matter in since this is an internal object, but should we ensure object is an ASTextRendererKey for correctness?
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 call. I added a comment explaining it.
Only un-CI'd changes are a comment I added. Landing! |
* Fix thread sanitizer warning in ASTextNodeRendererKey * Update changelog * Comment on missing class check
I made this before I saw that #819 exists, and while I think @hebertialmeida's solution may possibly be faster (though it could lead to thread explosion), I think this solution is more precise.
The race condition is in the C++ struct
ASTextKitAttributes
itself. Since there is no synchronization around the contents of that struct, the sanitizer is correctly warning us.This has led me down a heck of a rabbit-hole with memory safety. In lieu of a more general fix for the problem of creating very fast, but flexible and thread-safe C++ structures that interoperate well with Objective-C, this fix solves the thread sanitizer warnings in an appropriate way, by protecting access to that structure, at least in the
hash
andisEqual
methods, which seems sufficient since the class is specifically termed aKey
.Note that it's not sufficient to make the Objective-C property accessor atomic, since that seems only to protect the pointer. I don't know much about how synthesized atomic accessors treat c++ objects, but I wouldn't be surprised if they're not actually atomic.