I'd like clarification on the documentation for
isKnownUniquelyReferenced. It says:
If the instance passed as
objectis being accessed by multiple threads simultaneously, this function may still return
true. Therefore, you must only call this function from mutating methods with appropriate thread synchronization. That will ensure that
truewhen there is really one accessor, or when there is a race condition, which is already undefined behavior.
I don't really understand what this means.
I followed this Twitter conversation (Feb 2019) between Drew McCormack and @Joe_Groff (also nicely summarized by @mjtsai), in which Joe seems to say that
isKnownUniquelyReferenced is thread-safe because it takes its argument
inout and the exclusivity guarantee associated with
isUniquetakes its argument
inoutintentionally to ensure this isn't a problem. Swift's
inoutrequires exclusive access to the memory passed in, so by the time you have a local copy, it must be in a separate memory location with its own strong reference
In other words, because of the
isUniquereturning true also implies that your thread is the only thread that can see the one outstanding reference
@Joe_Groff I did not understand what you meant by this until I started writing this post. My original interpretation was that if two threads access pass the same reference to
isKnown… at the same time, it would be an exclusivity violation, but that can't be because that's a situation what
isKnown… should definitely handle.
I now think I confounded the variables containing the reference and the actual reference. New interpretation: as long as the two threads use separate variables to pass to
isKnown…, everything is fine because memory exclusivity applies to variables (i.e. locations in memory). That both variables contain a pointer to the same object is unrelated. Is this interpretation correct?
Having established (I hope) that
isKnown… is thread-safe, I still wonder what the documentation comment I quoted above hints at. Does it talk about the situation when two threads call
isKnown... simultaneously with the the same variable (i.e. a race condition on the variable)? If so, this is a programmer error that I understand.
When the documentation talks about "the instance passed as
object", does it refer to the variable or the object the variable points to?
PS: I also found this Dec 2017 thread that essentially asks the same question: Data races with copy-on-write. But the "bug" reported in that thread (SR-6543) turned out to be a thread sanitizer issue.