There could be a race condition between those 2 points. Imagine what happens if you execute the doSomething()
function on 2 separate threads like this:
- The first thread executes the
increaseWork()
closure and finishes it. It's at the line with wait right now
- The second thread starts executing and hits the async execute instruction
- The first thread hits the return instruction as the wait can continue
- At the same time, the closure from the second is scheduled and executed
At this point, you can't tell for sure what is executed first: the sum = sum + 100
from the second thread or the return sum
from the first one.
The idea is that sum
is a shared resource which is not synchronised, so, in theory, that could be a race condition. Even if you took care that such thing does not happen, the Thread Sanitizer detects a possible race condition as it does not know whether you start a single thread or you execute doSomething()
function from 100 different threads at the same time.
UPDATE:
As I missed the fact that the sum
variable is local, the above explanation does not answer the current question. The scenario described would never take place in the given piece of code.
But, even though the sum
is a local variable, due to the fact it is used and retained inside a closure, it will be allocated on heap, rather than on stack. That's because the Swift compiler cannot determine whether the closure will be finished its execution before the doSomething()
function return or not.
Why? Because the closure is passed to a constructor which behaves like an @escaping
parameter. It implies that there is no guarantee when the closure will be executed, thus all the variables retained by the closure must be allocated on heap for safety. Not knowing when the closure will be executed, the Thread Sanitizer cannot determine that the return sum
statement will be indeed executed after the closure finishes.
So even though here we can be sure that no race condition can happen, the Thread Sanitizer raises an alarm, as it cannot determine it cannot happen.