orchetect / OTAtomics

Multi-platform Swift thread-safe atomics library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`@OTAtomicsThreadSafe` wrapper not usable on local var within a method

orchetect opened this issue · comments

Issue

In its current implementation, @OTAtomicsThreadSafe is designed to work as a wrapper around variables installed in an object (class, struct, enum, etc.).

success

However it will strangely result in a data race when used on a variable declaration within a function. So this wrapper should not be used in this fashion.

The following code will almost always return a value that is less than 100:

fail

Proposal

It is poor form to declare a local variable within a function and then attempt to mutate it concurrently. Better form is to take the value and pass it into a concurrent operation that can run synchronously within the method, then rely on the operation to return the fully mutated value, often by way of a completion handler closure which can be waited on.

It is not clear if there is a way to prevent the property wrapper from being used on variable declarations inside a method, as the compiler will not stop you from doing it.

i remember us talking about that at some point when i was wondering if you could use it inside a function. Didn't we decide the safe way was to wrap the wrapper var in a struct?

It's mostly a paradigm shift - the concurrent code should do all its mutation externally, finish up, and return the final result synchronously within the method. But nothing should be concurrently mutating a local variable declared within the function.

A property wrapper is already wrapping the value, so adding more layers of wrapping won't really improve the situation. On the whole, there is no safe way to mutate a local var concurrently.

That's where something like the operations library I've worked on come in handy (OTOperations, based on NSOperation). You can wrap concurrent work in a BasicOperation and execute it synchronously within a method if you choose.

And there's a host of other API that do similar things in the standard lib or otherwise. Again, just a paradigm shift.