8
8
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9
9
//
10
10
11
+ #if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
11
12
private import _TestingInternals
13
+ #else
14
+ private import Synchronization
15
+ #endif
16
+
17
+ #if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
18
+ private nonisolated ( unsafe) let _fallbackEventHandler = {
19
+ let result = ManagedBuffer < FallbackEventHandler ? , os_unfair_lock > . create (
20
+ minimumCapacity: 1 ,
21
+ makingHeaderWith: { _ in nil }
22
+ )
23
+ result. withUnsafeMutablePointerToHeader { $0. initialize ( to: nil ) }
24
+ return result
25
+ } ( )
26
+ #else
27
+ private nonisolated ( unsafe) let _fallbackEventHandler = Atomic < UnsafeRawPointer ? > ( nil )
28
+ #endif
12
29
13
30
/// A type describing a fallback event handler to invoke when testing API is
14
31
/// used while the testing library is not running.
@@ -36,7 +53,19 @@ package typealias FallbackEventHandler = @Sendable @convention(c) (
36
53
/// ``setFallbackEventHandler(_:)`` and store its returned value.
37
54
@_cdecl ( " swift_testing_getFallbackEventHandler " )
38
55
package func fallbackEventHandler( ) -> FallbackEventHandler ? {
39
- swt_loadFallbackEventHandler ( )
56
+ #if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
57
+ return _fallbackEventHandler. withUnsafeMutablePointers { fallbackEventHandler, lock in
58
+ os_unfair_lock_lock ( lock)
59
+ defer {
60
+ os_unfair_lock_unlock ( lock)
61
+ }
62
+ return fallbackEventHandler. pointee
63
+ }
64
+ #else
65
+ return _fallbackEventHandler. load ( ordering: . sequentiallyConsistent) . map { fallbackEventHandler in
66
+ unsafeBitCast ( fallbackEventHandler, to: FallbackEventHandler ? . self)
67
+ }
68
+ #endif
40
69
}
41
70
42
71
/// Set the current fallback event handler if one has not already been set.
@@ -51,5 +80,20 @@ package func fallbackEventHandler() -> FallbackEventHandler? {
51
80
/// called and the handler set, it does not replace the previous handler.
52
81
@_cdecl ( " swift_testing_installFallbackEventHandler " )
53
82
package func installFallbackEventHandler( _ handler: FallbackEventHandler ) -> CBool {
54
- swt_installFallbackEventHandler ( handler)
83
+ #if SWT_TARGET_OS_APPLE && !SWT_NO_OS_UNFAIR_LOCK
84
+ return _fallbackEventHandler. withUnsafeMutablePointers { fallbackEventHandler, lock in
85
+ os_unfair_lock_lock ( lock)
86
+ defer {
87
+ os_unfair_lock_unlock ( lock)
88
+ }
89
+ guard fallbackEventHandler. pointee == nil else {
90
+ return false
91
+ }
92
+ fallbackEventHandler. pointee = handler
93
+ return true
94
+ }
95
+ #else
96
+ let handler = unsafeBitCast ( handler, to: UnsafeRawPointer . self)
97
+ return _fallbackEventHandler. compareExchange ( expected: nil , desired: handler, ordering: . sequentiallyConsistent) . exchanged
98
+ #endif
55
99
}
0 commit comments