isKnownUniquelyReferenced thread safety

isKnownUniquelyReferenced tells you whether the given variable holds a non-nil and unique reference to its current referent object.

isKnownUniquelyReferenced requires, as a precondition, that there be no racing modifications of the variable. That precondition does not need to be repeated in the documentation because it is true for every inout argument in Swift: as one aspect of the general prohibition on data races, if a variable is passed as an inout argument, then all other accesses to it must either happen-before the start of the call or happen-after the end of the call. Swift enforces that rule up to a certain point by default, and it enforces it a few steps further under TSan (or a few steps less if you turn off exclusivity checking), but ultimately it is your responsibility as a programmer to satisfy it. It is a goal of the eventual concurrency design of Swift that code which obeys certain rules globally will be guaranteed to not have data races, but we don't have that design yet, and even when we do, I don't foresee us ever completely banning raw uses of threads.

isKnownUniquelyReferenced does not need to be ordered with accesses to other variables that hold references to the variable's referent. If there are no races on the given variable, and there are no weak or unowned references to the variable's current referent, then if isKnownUniquelyReferenced returns true it is guaranteed that all accesses to the referent must be through the given variable. The converse is of course not true: if isKnownUniquelyReferenced returns false, it is still possible that there will be no further accesses to the referent through other references — for any number of reasons, races being probably the least significant.

isKnownUniquelyReferenced must take its argument inout because that is the only way in Swift today to abstractly refer to a variable. Other arguments are always semantically values, and "is this value the only reference to this object?" isn't a good question to ask because the answer is useless unless you've got another reference to the object that you can use afterwards, in which case presumably the answer to the question ought to be "no, because you've got another reference right over there". That's why the question has to be about whether a specific variable is the only way to refer to the object. Now, isKnownUniquelyReferenced could take an immutable reference to a variable, if we had such a thing, but we don't.

17 Likes