> On Jan 25, 2017, at 10:53 AM, Edward Connell via swift-users 
> <swift-users@swift.org> wrote:
> 
> I am implementing a custom Array type for a distributed memory system.
> 
> I have a DataView struct which represents the array to the user as a value 
> type, and a backing store class object referenced by the DataView that does 
> all the replication. Write accesses are mutating so they don't cause a 
> problem.
> 
> However read only accesses are not mutating and there lies the problem. If 
> the storage object is uniquely referenced, then I can do my business without 
> taking a synchronization lock, otherwise I need to take a lock before syncing 
> memory.
> 
> I can "always" take a lock to work around this, but most of the time it isn't 
> necessary and I care about performance.
> 
> I think there should be a "read only pass by reference"
> 
> I just pulled this comment from the source code. I was under the impression 
> that isKnownUniquelyReferenced is thread safe, but the comments implies that 
> it isn't??

If you implement the copy-on-write backing store correctly, as done with 
ContiguousArray, then you don’t need to worry about multiple threads sharing 
the same storage. That’s not a race because none of the threads can mutate the 
storage without first making a local copy.

So, if you pass the DataView object off to another thread by value, then you’ll 
be fine. Each thread will have it’s own logical copy of the data. 
`isUniquelyReferenced` will return `false` for any thread that has a copy.

Now, if the DataView struct is itself a shared object, either by virtue of 
being stored in a global or a class property, then you have to worry about 
races. Any thread calling `isUniquelyReferenced` on that object should have 
exclusive access to the object at that time. In other words, 
`isUniquelyReferenced` should be thought of as a “write” to the location that 
stores the reference to your storage. In that sense, `inout` is again 
semantically correct even though it doesn’t change the value.

It sounds like you want to use the refcount of the data storage as 
synchronization on the data value itself which doesn’t work. If the data value 
is in a class property, that class  needs its own synchronization. Or just 
always pass DataView by value and don’t store it in shared class properties.

Hope that makes sense!

-Andy

> 
> ------------------------------
> /// If the instance passed as `object` is 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 `isKnownUniquelyReferenced(_:)`
> /// only returns `true` when there is really one accessor, or when there is a
> /// race condition, which is already undefined behavior.
> ///
> /// - Parameter object: An instance of a class. This function does *not* 
> modify
> ///   `object`; the use of `inout` is an implementation artifact.
> 
> 
> 
> On Wed, Jan 25, 2017 at 10:31 AM, Joe Groff <jgr...@apple.com 
> <mailto:jgr...@apple.com>> wrote:
> 
> > On Jan 25, 2017, at 10:20 AM, Edward Connell via swift-users 
> > <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
> >
> > I have a data structure that calls isKnownUniquelyReferenced on a member. 
> > It forces everything to be marked as mutating because of the inout 
> > parameter, however the parameter is never mutated, it is just read right?? 
> > The reason it is inout is because a read only reference is required.
> >
> > If it is truly not mutating, is there some way around this so I don't have 
> > to mark everything in the caller chain as mutating also? It's kind of 
> > annoying...
> 
> In Swift's current model, `isKnownUniquelyReferenced` needs to be inout 
> because that's currently the only way to assert unique access to an object in 
> memory, since read-only rvalues are otherwise freely copyable so the result 
> of the uniqueness check would be only momentarily valid at best. What are you 
> trying to do that requires using it on a nonmutable value? There may be 
> another way to go about it.
> 
> -Joe
> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to