Post

Replies

Boosts

Views

Activity

How to avoid Data Races in deinit
Analysing my code with the new exciting Thread Sanitizer tool from Xcode 8, in certain scenarios I'm experiencing unexpected data races in `deinit` of classes which protect the access to their properties with a synchronization primitive (a dispatch queue) .Given a class, with a "sync queue" and a synchronized member value:enum MyEnum { case first(_: String) case second(_: [String]) } public class Foo { private let _syncQueue = DispatchQueue(label: "foo-sync-queue", attributes: .serial) private var _value: MyEnum = .first("") public init() { } deinit { } public func modify(value: String) { _syncQueue.async { self._value = .first(value) } } }What's not immediately obvious is the fact, that the deinit method must access the enum in order to figure out how to deallocate the underlying value.Suppose, method `modify` will be executed on Thread A. This causes the actual write operation to be executed on a thread, say M, which is synchronized with the `syncQueue`.It may happen that Thread A equals Thread M, but that is random.Now, suppose a reference to variable of type `Foo` exists in Thread B. It happens that this is the last strong reference to the variable. Now, when this variable ceases to exist, the `deinit` method of the variable will be called. This deinit reads from the memory store for member `_value`. This read operation is not synchronized with the sync queue. Since the executing thread happens to be not equal the thread M, where the previous write operation has been performed, a data race occurs.This data race is not easy to fix. I dare to state, it is even impossible in certain use cases. For example:Suppose there is a function which returns a new value of type Foo:func createFoo() -> FooAnd then:createFoo().modify(value: "Hello Data Race")The problem here is, that the live-time of the returned temporary is largely uncontrollable by the programmer. This prevents the programmer to determine _when_ the variable foo should be deallocated. And to be honest, a programmer shouldn't care about these details anyway!In practice, this creates a very reliable data race.This use case is not artificial in the functional paradigm. Actually, I'm having this issue, and I have no idea how to fix it - except there would be help with a corresponding language construct (e.g. let us implement the deinit function) - which does not currently exists.Any ideas are appreciated.
5
0
4.9k
Jun ’16
Playground crash: AttributeGraph precondition failure: setting value during update
I get an error: error: Execution was interrupted, reason: signal SIGABRT. The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation. when running the following minimal playground code in Xcode: Swift import SwiftUI import PlaygroundSupport struct Country: Identifiable {     var id: String { name }     var name: String     var flag: String } struct CountryView: View {     let name: String     let flag: String     var body: some View {         Text(name)     } } PlaygroundPage.current.setLiveView(     ForEach([Country(name: "Italy", flag: "italy")], id: \.id) { country in         CountryView(name: country.name, flag: country.flag)     } ) This is for current Xcode Version 12.4 (12D4e), and beta3. Note that Xcode does not crash. It's the playground execution. Any hints for a workaround? Additional notes: Currently, playground seem to have a lot if issues and it's currently not usable as a whole - even without using SwiftUI there are a lot issues resulting in crashes, which I think is a very bad situation. A crash log is generated when executing the playground. Part of the crash log: Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY External Modification Warnings: Debugger attached to process. Application Specific Information: abort() called CoreSimulator 757.3 - Device: iPad Pro (9.7-inch) (28657173-2D19-4421-B084-2F4DDD658725) - Runtime: iOS 14.4 (18D46) - DeviceType: iPad Pro (9.7-inch) AttributeGraph precondition failure: setting value during update: 5656. Crash Log - https://developer.apple.com/forums/content/attachment/1d99662f-a766-4cd0-a002-a37f7de2dce0
1
0
1.9k
Apr ’21