26
26
//
27
27
//===----------------------------------------------------------------------===//
28
28
29
- #if canImport(Darwin)
29
+ #if canImport(WASILibc)
30
+ // No locking on WASILibc
31
+ #elseif canImport(Darwin)
30
32
import Darwin
33
+ #elseif os(Windows)
34
+ import WinSDK
31
35
#elseif canImport(Glibc)
32
36
import Glibc
33
37
#elseif canImport(Android)
@@ -50,45 +54,89 @@ import wasi_pthread
50
54
/// one used by NIO.
51
55
@_spi ( Locking) // Use the `package` access modifier once min Swift version is increased.
52
56
public 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
54
65
55
66
/// Create a new lock.
56
67
public init ( ) {
68
+ #if canImport(WASILibc)
69
+ // WASILibc is single threaded, provides no locks
70
+ #elseif os(Windows)
71
+ InitializeSRWLock ( self . rwlock)
72
+ #else
57
73
let err = pthread_rwlock_init ( self . rwlock, nil )
58
74
precondition ( err == 0 , " pthread_rwlock_init failed with error \( err) " )
75
+ #endif
59
76
}
60
77
61
78
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
62
85
let err = pthread_rwlock_destroy ( self . rwlock)
63
86
precondition ( err == 0 , " pthread_rwlock_destroy failed with error \( err) " )
64
87
self . rwlock. deallocate ( )
88
+ #endif
65
89
}
66
90
67
91
/// Acquire a reader lock.
68
92
///
69
93
/// Whenever possible, consider using `withLock` instead of this method and
70
94
/// `unlock`, to simplify lock handling.
71
95
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
72
102
let err = pthread_rwlock_rdlock ( self . rwlock)
73
103
precondition ( err == 0 , " pthread_rwlock_rdlock failed with error \( err) " )
104
+ #endif
74
105
}
75
106
76
107
/// Acquire a writer lock.
77
108
///
78
109
/// Whenever possible, consider using `withLock` instead of this method and
79
110
/// `unlock`, to simplify lock handling.
80
111
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
81
118
let err = pthread_rwlock_wrlock ( self . rwlock)
82
119
precondition ( err == 0 , " pthread_rwlock_wrlock failed with error \( err) " )
120
+ #endif
83
121
}
84
122
85
123
/// Release the lock.
86
124
///
87
125
/// Whenever possible, consider using `withLock` instead of this method and
88
126
/// `lock`, to simplify lock handling.
89
127
public func unlock( ) {
128
+ #if canImport(WASILibc)
129
+ // WASILibc is single threaded, provides no locks
130
+ #elseif os(Windows)
131
+ if self . shared {
132
+ ReleaseSRWLockShared ( self . rwlock)
133
+ } else {
134
+ ReleaseSRWLockExclusive ( self . rwlock)
135
+ }
136
+ #else
90
137
let err = pthread_rwlock_unlock ( self . rwlock)
91
138
precondition ( err == 0 , " pthread_rwlock_unlock failed with error \( err) " )
139
+ #endif
92
140
}
93
141
}
94
142
0 commit comments