Possible data race in function `subscribe`
couchdeveloper opened this issue · 0 comments
couchdeveloper commented
In function subscribe
public func subscribe(f: Result<T> -> Void) -> Signal<T> {
if let value = value {
f(value)
}
mutex.lock {
callbacks.append(f)
}
return self
}
https://github.com/JensRavens/Interstellar/blob/master/Sources/Signal.swift#L145-L153
it seems to me, there's a potential data race: access to value
should be protected by the mutex.
Proposed solution:
public func subscribe(f: Result<T> -> Void) -> Signal<T> {
var v: Result<T>?
mutex.lock {
v = self.value
callbacks.append(f)
}
if let value = v {
f(value)
}
return self
}
Still, this is not a reliable solution: it's not guaranteed, that function f
will be invoked before any other mapping function which is invoked due to an update. These kind of issues can be solved only with introducing an "execution context" (for example a dispatch queue) which defines where the mapping function will be executed:
public func subscribe(ec: ExecutionContext = <default>, f: Result<T> -> Void) -> Signal<T> {
mutex.lock {
if let value = self.value {
ec.execAsync { f(value) }
}
callbacks.append(f)
}
return self
}