2626//
2727//===----------------------------------------------------------------------===//
2828
29- #if canImport(Darwin)
29+ #if canImport(WASILibc)
30+ // No locking on WASILibc
31+ #elseif canImport(Darwin)
3032import Darwin
33+ #elseif os(Windows)
34+ import WinSDK
3135#elseif canImport(Glibc)
3236import Glibc
3337#elseif canImport(Android)
@@ -50,45 +54,90 @@ import wasi_pthread
5054/// one used by NIO.
5155@_spi ( Locking) // Use the `package` access modifier once min Swift version is increased.
5256public final class ReadWriteLock {
53- private let rwlock : UnsafeMutablePointer < pthread_rwlock_t > = UnsafeMutablePointer . allocate ( capacity: 1 )
57+ #if canImport(WASILibc)
58+ // WASILibc is single threaded, provides no locks
59+ #elseif os(Windows)
60+ fileprivate let mutex : UnsafeMutablePointer < SRWLOCK > =
61+ UnsafeMutablePointer . allocate ( capacity: 1 )
62+ #else
63+ fileprivate let rwlock : UnsafeMutablePointer < pthread_rwlock_t > = UnsafeMutablePointer . allocate ( capacity: 1 )
64+ #endif
5465
5566 /// Create a new lock.
5667 public init ( ) {
68+ #if canImport(WASILibc)
69+ // WASILibc is single threaded, provides no locks
70+ #elseif os(Windows)
71+ InitializeSRWLock ( self . rwlock)
72+ #else
5773 let err = pthread_rwlock_init ( self . rwlock, nil )
5874 precondition ( err == 0 , " pthread_rwlock_init failed with error \( err) " )
75+ #endif
5976 }
6077
6178 deinit {
79+ #if canImport(WASILibc)
80+ // WASILibc is single threaded, provides no locks
81+ #elseif os(Windows)
82+ // SRWLOCK does not need to be free'd
83+ self . rwlock. deallocate ( )
84+ #else
6285 let err = pthread_rwlock_destroy ( self . rwlock)
6386 precondition ( err == 0 , " pthread_rwlock_destroy failed with error \( err) " )
6487 self . rwlock. deallocate ( )
88+ #endif
6589 }
6690
6791 /// Acquire a reader lock.
6892 ///
6993 /// Whenever possible, consider using `withLock` instead of this method and
7094 /// `unlock`, to simplify lock handling.
7195 public func lockRead( ) {
96+ #if canImport(WASILibc)
97+ // WASILibc is single threaded, provides no locks
98+ #elseif os(Windows)
99+ AcquireSRWLockShared ( self . rwlock)
100+ self . shared = true
101+ #else
72102 let err = pthread_rwlock_rdlock ( self . rwlock)
73103 precondition ( err == 0 , " pthread_rwlock_rdlock failed with error \( err) " )
104+ #endif
74105 }
75106
76107 /// Acquire a writer lock.
77108 ///
78109 /// Whenever possible, consider using `withLock` instead of this method and
79110 /// `unlock`, to simplify lock handling.
80111 public func lockWrite( ) {
112+ #if canImport(WASILibc)
113+ // WASILibc is single threaded, provides no locks
114+ #elseif os(Windows)
115+ AcquireSRWLockExclusive ( self . rwlock)
116+ self . shared = false
117+ #else
81118 let err = pthread_rwlock_wrlock ( self . rwlock)
82119 precondition ( err == 0 , " pthread_rwlock_wrlock failed with error \( err) " )
120+ #endif
83121 }
84122
85123 /// Release the lock.
86124 ///
87125 /// Whenever possible, consider using `withLock` instead of this method and
88126 /// `lock`, to simplify lock handling.
127+ /// handling.
89128 public func unlock( ) {
129+ #if canImport(WASILibc)
130+ // WASILibc is single threaded, provides no locks
131+ #elseif os(Windows)
132+ if self . shared {
133+ ReleaseSRWLockShared ( self . rwlock)
134+ } else {
135+ ReleaseSRWLockExclusive ( self . rwlock)
136+ }
137+ #else
90138 let err = pthread_rwlock_unlock ( self . rwlock)
91139 precondition ( err == 0 , " pthread_rwlock_unlock failed with error \( err) " )
140+ #endif
92141 }
93142}
94143
0 commit comments