@@ -24,6 +24,13 @@ import WinSDK
2424import Glibc
2525#elseif canImport(Musl)
2626import 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
2734#else
2835#error("The concurrency NIOLock module was unable to identify your C library.")
2936#endif
@@ -37,16 +44,16 @@ typealias LockPrimitive = pthread_mutex_t
3744#endif
3845
3946@usableFromInline
40- enum LockOperations { }
47+ enum LockOperations { }
4148
4249extension LockOperations {
4350 @inlinable
4451 static func create( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
4552 mutex. assertValidAlignment ( )
4653
47- #if os(Windows)
54+ #if os(Windows)
4855 InitializeSRWLock ( mutex)
49- #else
56+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
5057 var attr = pthread_mutexattr_t ( )
5158 pthread_mutexattr_init ( & attr)
5259 debugOnly {
@@ -55,43 +62,43 @@ extension LockOperations {
5562
5663 let err = pthread_mutex_init ( mutex, & attr)
5764 precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
58- #endif
65+ #endif
5966 }
6067
6168 @inlinable
6269 static func destroy( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
6370 mutex. assertValidAlignment ( )
6471
65- #if os(Windows)
72+ #if os(Windows)
6673 // SRWLOCK does not need to be free'd
67- #else
74+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
6875 let err = pthread_mutex_destroy ( mutex)
6976 precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
70- #endif
77+ #endif
7178 }
7279
7380 @inlinable
7481 static func lock( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
7582 mutex. assertValidAlignment ( )
7683
77- #if os(Windows)
84+ #if os(Windows)
7885 AcquireSRWLockExclusive ( mutex)
79- #else
86+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
8087 let err = pthread_mutex_lock ( mutex)
8188 precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
82- #endif
89+ #endif
8390 }
8491
8592 @inlinable
8693 static func unlock( _ mutex: UnsafeMutablePointer < LockPrimitive > ) {
8794 mutex. assertValidAlignment ( )
8895
89- #if os(Windows)
96+ #if os(Windows)
9097 ReleaseSRWLockExclusive ( mutex)
91- #else
98+ #elseif (compiler(<6.1) && !os(WASI)) || (compiler(>=6.1) && _runtime(_multithreaded))
9299 let err = pthread_mutex_unlock ( mutex)
93100 precondition ( err == 0 , " \( #function) failed in pthread_mutex with error \( err) " )
94- #endif
101+ #endif
95102 }
96103}
97104
@@ -129,9 +136,11 @@ final class LockStorage<Value>: ManagedBuffer<Value, LockPrimitive> {
129136 @inlinable
130137 static func create( value: Value ) -> Self {
131138 let buffer = Self . create ( minimumCapacity: 1 ) { _ in
132- return value
139+ value
133140 }
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
135144 let storage = buffer as! Self
136145
137146 storage. withUnsafeMutablePointers { _, lockPtr in
@@ -165,7 +174,7 @@ final class LockStorage<Value>: ManagedBuffer<Value, LockPrimitive> {
165174 @inlinable
166175 func withLockPrimitive< T> ( _ body: ( UnsafeMutablePointer < LockPrimitive > ) throws -> T ) rethrows -> T {
167176 try self . withUnsafeMutablePointerToElements { lockPtr in
168- return try body ( lockPtr)
177+ try body ( lockPtr)
169178 }
170179 }
171180
@@ -179,17 +188,14 @@ final class LockStorage<Value>: ManagedBuffer<Value, LockPrimitive> {
179188 }
180189}
181190
182- extension LockStorage : @unchecked Sendable { }
183-
184191/// A threading lock based on `libpthread` instead of `libdispatch`.
185192///
186- /// - note : ``NIOLock`` has reference semantics.
193+ /// - Note : ``NIOLock`` has reference semantics.
187194///
188195/// This object provides a lock on top of a single `pthread_mutex_t`. This kind
189196/// of lock is safe to use with `libpthread`-based threading models, such as the
190197/// one used by NIO. On Windows, the lock is based on the substantially similar
191198/// `SRWLOCK` type.
192- @usableFromInline
193199struct NIOLock {
194200 @usableFromInline
195201 internal let _storage : LockStorage < Void >
@@ -220,7 +226,7 @@ struct NIOLock {
220226
221227 @inlinable
222228 internal func withLockPrimitive< T> ( _ body: ( UnsafeMutablePointer < LockPrimitive > ) throws -> T ) rethrows -> T {
223- return try self . _storage. withLockPrimitive ( body)
229+ try self . _storage. withLockPrimitive ( body)
224230 }
225231}
226232
@@ -243,12 +249,12 @@ extension NIOLock {
243249 }
244250
245251 @inlinable
246- func withLockVoid( _ body: ( ) throws -> Void ) rethrows -> Void {
252+ func withLockVoid( _ body: ( ) throws -> Void ) rethrows {
247253 try self . withLock ( body)
248254 }
249255}
250256
251- extension NIOLock : Sendable { }
257+ extension NIOLock : @ unchecked Sendable { }
252258
253259extension UnsafeMutablePointer {
254260 @inlinable
@@ -264,6 +270,10 @@ extension UnsafeMutablePointer {
264270/// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion.
265271@inlinable
266272internal func debugOnly( _ body: ( ) -> Void ) {
267- // FIXME: duplicated with NIO.
268- assert ( { body ( ) ; return true } ( ) )
273+ assert (
274+ {
275+ body ( )
276+ return true
277+ } ( )
278+ )
269279}
0 commit comments