@@ -24,6 +24,13 @@ import WinSDK
24
24
import Glibc
25
25
#elseif canImport(Musl)
26
26
import Musl
27
+ #elseif canImport(Bionic)
28
+ import Bionic
29
+ #elseif canImport(WASILibc)
30
+ import WASILibc
31
+ #if canImport(wasi_pthread)
32
+ import wasi_pthread
33
+ #endif
27
34
#else
28
35
#error("The concurrency NIOLock module was unable to identify your C library.")
29
36
#endif
@@ -37,16 +44,16 @@ typealias LockPrimitive = pthread_mutex_t
37
44
#endif
38
45
39
46
@usableFromInline
40
- enum LockOperations { }
47
+ enum LockOperations { }
41
48
42
49
extension LockOperations {
43
50
@inlinable
44
51
static func create( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
45
52
mutex. assertValidAlignment ( )
46
53
47
- #if os(Windows)
54
+ #if os(Windows)
48
55
InitializeSRWLock ( mutex)
49
- #else
56
+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
50
57
var attr = pthread_mutexattr_t ( )
51
58
pthread_mutexattr_init ( & attr)
52
59
debugOnly {
@@ -55,43 +62,43 @@ extension LockOperations {
55
62
56
63
let err = pthread_mutex_init ( mutex, & attr)
57
64
precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
58
- #endif
65
+ #endif
59
66
}
60
67
61
68
@inlinable
62
69
static func destroy( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
63
70
mutex. assertValidAlignment ( )
64
71
65
- #if os(Windows)
72
+ #if os(Windows)
66
73
// SRWLOCK does not need to be free'd
67
- #else
74
+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
68
75
let err = pthread_mutex_destroy ( mutex)
69
76
precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
70
- #endif
77
+ #endif
71
78
}
72
79
73
80
@inlinable
74
81
static func lock( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
75
82
mutex. assertValidAlignment ( )
76
83
77
- #if os(Windows)
84
+ #if os(Windows)
78
85
AcquireSRWLockExclusive ( mutex)
79
- #else
86
+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
80
87
let err = pthread_mutex_lock ( mutex)
81
88
precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
82
- #endif
89
+ #endif
83
90
}
84
91
85
92
@inlinable
86
93
static func unlock( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
87
94
mutex. assertValidAlignment ( )
88
95
89
- #if os(Windows)
96
+ #if os(Windows)
90
97
ReleaseSRWLockExclusive ( mutex)
91
- #else
98
+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
92
99
let err = pthread_mutex_unlock ( mutex)
93
100
precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
94
- #endif
101
+ #endif
95
102
}
96
103
}
97
104
@@ -129,9 +136,11 @@ final class LockStorage<Value>: ManagedBuffer<Value, LockPrimitive> {
129
136
@inlinable
130
137
static func create( value: Value ) -> Self {
131
138
let buffer = Self . create ( minimumCapacity: 1 ) { _ in
132
- return value
139
+ value
133
140
}
134
- // Avoid 'unsafeDowncast' as there is a miscompilation on 5.10.
141
+ // Intentionally using a force cast here to avoid a miss compiliation in 5.10.
142
+ // This is as fast as an unsafeDownCast since ManagedBuffer is inlined and the optimizer
143
+ // can eliminate the upcast/downcast pair
135
144
let storage = buffer as! Self
136
145
137
146
storage. withUnsafeMutablePointers { _, lockPtr in
@@ -165,7 +174,7 @@ final class LockStorage<Value>: ManagedBuffer<Value, LockPrimitive> {
165
174
@inlinable
166
175
func withLockPrimitive< T> ( _ body: ( UnsafeMutablePointer < LockPrimitive > ) throws -> T ) rethrows -> T {
167
176
try self . withUnsafeMutablePointerToElements { lockPtr in
168
- return try body ( lockPtr)
177
+ try body ( lockPtr)
169
178
}
170
179
}
171
180
@@ -179,17 +188,14 @@ final class LockStorage<Value>: ManagedBuffer<Value, LockPrimitive> {
179
188
}
180
189
}
181
190
182
- extension LockStorage : @unchecked Sendable { }
183
-
184
191
/// A threading lock based on `libpthread` instead of `libdispatch`.
185
192
///
186
- /// - note : ``NIOLock`` has reference semantics.
193
+ /// - Note : ``NIOLock`` has reference semantics.
187
194
///
188
195
/// This object provides a lock on top of a single `pthread_mutex_t`. This kind
189
196
/// of lock is safe to use with `libpthread`-based threading models, such as the
190
197
/// one used by NIO. On Windows, the lock is based on the substantially similar
191
198
/// `SRWLOCK` type.
192
- @usableFromInline
193
199
struct NIOLock {
194
200
@usableFromInline
195
201
internal let _storage : LockStorage < Void >
@@ -220,7 +226,7 @@ struct NIOLock {
220
226
221
227
@inlinable
222
228
internal func withLockPrimitive< T> ( _ body: ( UnsafeMutablePointer < LockPrimitive > ) throws -> T ) rethrows -> T {
223
- return try self . _storage. withLockPrimitive ( body)
229
+ try self . _storage. withLockPrimitive ( body)
224
230
}
225
231
}
226
232
@@ -243,12 +249,12 @@ extension NIOLock {
243
249
}
244
250
245
251
@inlinable
246
- func withLockVoid( _ body: ( ) throws -> Void ) rethrows -> Void {
252
+ func withLockVoid( _ body: ( ) throws -> Void ) rethrows {
247
253
try self . withLock ( body)
248
254
}
249
255
}
250
256
251
- extension NIOLock : Sendable { }
257
+ extension NIOLock : @ unchecked Sendable { }
252
258
253
259
extension UnsafeMutablePointer {
254
260
@inlinable
@@ -264,6 +270,10 @@ extension UnsafeMutablePointer {
264
270
/// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion.
265
271
@inlinable
266
272
internal func debugOnly( _ body: ( ) -> Void ) {
267
- // FIXME: duplicated with NIO.
268
- assert ( { body ( ) ; return true } ( ) )
273
+ assert (
274
+ {
275
+ body ( )
276
+ return true
277
+ } ( )
278
+ )
269
279
}
0 commit comments