Files
swift-mirror/validation-test/stdlib/ErrorProtocol.swift
Doug Gregor e07e88706d Eliminate race in swift_bridgeErrorToNSError.
Huge thanks to John for noting that 'consume' didn't provide the
guarantees we wanted, and to Michael G. for getting a TSan build up
and running to identify/verify this race.

It's possible that this is overlay strict, and that we only need to
look at the domain to ensure that the code and userInfo are
visible. However, TSan seems to prefix the form in this patch, so
we'll be more conservative for now.

Fixes rdar://problem/27541751.
2016-08-03 15:21:15 -07:00

54 lines
1.4 KiB
Swift

// RUN: %target-run-simple-swift
// REQUIRES: executable_test
// REQUIRES: objc_interop
import SwiftPrivate
import StdlibUnittest
import Foundation
enum SomeError : Error {
case GoneToFail
}
struct ErrorAsNSErrorRaceTest : RaceTestWithPerTrialData {
class RaceData {
let error: Error
init(error: Error) {
self.error = error
}
}
func makeRaceData() -> RaceData {
return RaceData(error: SomeError.GoneToFail)
}
func makeThreadLocalData() {}
func thread1(_ raceData: RaceData, _: inout Void) -> Observation3Int {
let ns = raceData.error as NSError
// Use valueForKey to bypass bridging, so we can verify that the identity
// of the unbridged NSString object is stable.
let domainInt: Int = unsafeBitCast(ns.value(forKey: "domain").map { $0 as AnyObject },
to: Int.self)
let code: Int = ns.code
let userInfoInt: Int = unsafeBitCast(ns.value(forKey: "userInfo").map { $0 as AnyObject },
to: Int.self)
return Observation3Int(domainInt, code, userInfoInt)
}
func evaluateObservations(
_ observations: [Observation3Int],
_ sink: (RaceTestObservationEvaluation) -> Void
) {
sink(evaluateObservationsAllEqual(observations))
}
}
var ErrorRaceTestSuite = TestSuite("Error races")
ErrorRaceTestSuite.test("NSError bridging") {
runRaceTest(ErrorAsNSErrorRaceTest.self, operations: 1000)
}
runAllTests()