| 
29 | 29 | //  SOFTWARE.  | 
30 | 30 | //  | 
31 | 31 | 
 
  | 
32 |  | -// Backports the Swift 6 type Mutex<Value> to all Darwin platforms  | 
33 |  | -@usableFromInline  | 
34 |  | -struct Mutex<Value: ~Copyable>: ~Copyable {  | 
35 |  | -    let storage: Storage<Value>  | 
 | 32 | +#if !canImport(Darwin)  | 
36 | 33 | 
 
  | 
37 |  | -    @usableFromInline  | 
38 |  | -    init(_ initialValue: consuming sending Value) {  | 
39 |  | -        self.storage = Storage(initialValue)  | 
40 |  | -    }  | 
 | 34 | +import Synchronization  | 
41 | 35 | 
 
  | 
42 |  | -    @usableFromInline  | 
43 |  | -    borrowing func withLock<Result, E: Error>(  | 
44 |  | -        _ body: (inout sending Value) throws(E) -> sending Result  | 
45 |  | -    ) throws(E) -> sending Result {  | 
46 |  | -        storage.lock()  | 
47 |  | -        defer { storage.unlock() }  | 
48 |  | -        return try body(&storage.value)  | 
49 |  | -    }  | 
50 |  | - | 
51 |  | -    @usableFromInline  | 
52 |  | -    borrowing func withLockIfAvailable<Result, E: Error>(  | 
53 |  | -        _ body: (inout sending Value) throws(E) -> sending Result  | 
54 |  | -    ) throws(E) -> sending Result? {  | 
55 |  | -        guard storage.tryLock() else { return nil }  | 
56 |  | -        defer { storage.unlock() }  | 
57 |  | -        return try body(&storage.value)  | 
58 |  | -    }  | 
59 |  | -}  | 
60 |  | - | 
61 |  | -extension Mutex: @unchecked Sendable where Value: ~Copyable { }  | 
62 |  | - | 
63 |  | -#if canImport(Darwin)  | 
64 |  | - | 
65 |  | -import struct os.os_unfair_lock_t  | 
66 |  | -import struct os.os_unfair_lock  | 
67 |  | -import func os.os_unfair_lock_lock  | 
68 |  | -import func os.os_unfair_lock_unlock  | 
69 |  | -import func os.os_unfair_lock_trylock  | 
70 |  | - | 
71 |  | -final class Storage<Value: ~Copyable> {  | 
72 |  | -    private let _lock: os_unfair_lock_t  | 
73 |  | -    var value: Value  | 
74 |  | - | 
75 |  | -    init(_ initialValue: consuming Value) {  | 
76 |  | -        self._lock = .allocate(capacity: 1)  | 
77 |  | -        self._lock.initialize(to: os_unfair_lock())  | 
78 |  | -        self.value = initialValue  | 
79 |  | -    }  | 
80 |  | - | 
81 |  | -    func lock() {  | 
82 |  | -        os_unfair_lock_lock(_lock)  | 
83 |  | -    }  | 
84 |  | - | 
85 |  | -    func unlock() {  | 
86 |  | -        os_unfair_lock_unlock(_lock)  | 
87 |  | -    }  | 
88 |  | - | 
89 |  | -    func tryLock() -> Bool {  | 
90 |  | -        os_unfair_lock_trylock(_lock)  | 
91 |  | -    }  | 
92 |  | - | 
93 |  | -    deinit {  | 
94 |  | -        self._lock.deinitialize(count: 1)  | 
95 |  | -        self._lock.deallocate()  | 
96 |  | -    }  | 
97 |  | -}  | 
98 |  | - | 
99 |  | -#elseif canImport(Glibc) || canImport(Musl) || canImport(Bionic)  | 
100 |  | - | 
101 |  | -#if canImport(Musl)  | 
102 |  | -import Musl  | 
103 |  | -#elseif canImport(Bionic)  | 
104 |  | -import Android  | 
105 |  | -#else  | 
106 |  | -import Glibc  | 
107 |  | -#endif  | 
108 |  | - | 
109 |  | -final class Storage<Value: ~Copyable> {  | 
110 |  | -    private let _lock: UnsafeMutablePointer<pthread_mutex_t>  | 
111 |  | - | 
112 |  | -    var value: Value  | 
113 |  | - | 
114 |  | -    init(_ initialValue: consuming Value) {  | 
115 |  | -        var attr = pthread_mutexattr_t()  | 
116 |  | -        pthread_mutexattr_init(&attr)  | 
117 |  | -        self._lock = .allocate(capacity: 1)  | 
118 |  | -        let err = pthread_mutex_init(self._lock, &attr)  | 
119 |  | -        precondition(err == 0, "pthread_mutex_init error: \(err)")  | 
120 |  | -        self.value = initialValue  | 
121 |  | -    }  | 
122 |  | - | 
123 |  | -    func lock() {  | 
124 |  | -        let err = pthread_mutex_lock(_lock)  | 
125 |  | -        precondition(err == 0, "pthread_mutex_lock error: \(err)")  | 
126 |  | -    }  | 
127 |  | - | 
128 |  | -    func unlock() {  | 
129 |  | -        let err = pthread_mutex_unlock(_lock)  | 
130 |  | -        precondition(err == 0, "pthread_mutex_unlock error: \(err)")  | 
131 |  | -    }  | 
132 |  | - | 
133 |  | -    func tryLock() -> Bool {  | 
134 |  | -        pthread_mutex_trylock(_lock) == 0  | 
135 |  | -    }  | 
136 |  | - | 
137 |  | -    deinit {  | 
138 |  | -        let err = pthread_mutex_destroy(self._lock)  | 
139 |  | -        precondition(err == 0, "pthread_mutex_destroy error: \(err)")  | 
140 |  | -        self._lock.deallocate()  | 
141 |  | -    }  | 
142 |  | -}  | 
143 |  | - | 
144 |  | -#elseif canImport(WinSDK)  | 
145 |  | - | 
146 |  | -import ucrt  | 
147 |  | -import WinSDK  | 
148 |  | - | 
149 |  | -final class Storage<Value> {  | 
150 |  | -    private let _lock: UnsafeMutablePointer<SRWLOCK>  | 
151 |  | - | 
152 |  | -    var value: Value  | 
153 |  | - | 
154 |  | -    init(_ initialValue: Value) {  | 
155 |  | -        self._lock = .allocate(capacity: 1)  | 
156 |  | -        InitializeSRWLock(self._lock)  | 
157 |  | -        self.value = initialValue  | 
158 |  | -    }  | 
159 |  | - | 
160 |  | -    func lock() {  | 
161 |  | -        AcquireSRWLockExclusive(_lock)  | 
162 |  | -    }  | 
163 |  | - | 
164 |  | -    func unlock() {  | 
165 |  | -        ReleaseSRWLockExclusive(_lock)  | 
166 |  | -    }  | 
167 |  | - | 
168 |  | -    func tryLock() -> Bool {  | 
169 |  | -        TryAcquireSRWLockExclusive(_lock) != 0  | 
170 |  | -    }  | 
171 |  | -}  | 
 | 36 | +typealias Mutext = Synchronization.Mute  | 
172 | 37 | 
 
  | 
173 | 38 | #endif  | 
0 commit comments