28
28
29
29
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
30
30
import Darwin
31
+ #elseif os(Windows)
32
+ import WinSDK
31
33
#else
32
34
import Glibc
33
35
#endif
@@ -38,17 +40,31 @@ import Glibc
38
40
/// of lock is safe to use with `libpthread`-based threading models, such as the
39
41
/// one used by NIO.
40
42
internal final class Lock {
41
- fileprivate let mutex : UnsafeMutablePointer < pthread_mutex_t > = UnsafeMutablePointer . allocate ( capacity: 1 )
43
+ #if os(Windows)
44
+ fileprivate let mutex : UnsafeMutablePointer < SRWLOCK > =
45
+ UnsafeMutablePointer . allocate ( capacity: 1 )
46
+ #else
47
+ fileprivate let mutex : UnsafeMutablePointer < pthread_mutex_t > =
48
+ UnsafeMutablePointer . allocate ( capacity: 1 )
49
+ #endif
42
50
43
51
/// Create a new lock.
44
52
public init ( ) {
53
+ #if os(Windows)
54
+ InitializeSRWLock ( self . mutex)
55
+ #else
45
56
let err = pthread_mutex_init ( self . mutex, nil )
46
57
precondition ( err == 0 )
58
+ #endif
47
59
}
48
60
49
61
deinit {
62
+ #if os(Windows)
63
+ // SRWLOCK does not need to be free'd
64
+ #else
50
65
let err = pthread_mutex_destroy ( self . mutex)
51
66
precondition ( err == 0 )
67
+ #endif
52
68
self . mutex. deallocate ( )
53
69
}
54
70
@@ -57,17 +73,25 @@ internal final class Lock {
57
73
/// Whenever possible, consider using `withLock` instead of this method and
58
74
/// `unlock`, to simplify lock handling.
59
75
public func lock( ) {
76
+ #if os(Windows)
77
+ AcquireSRWLockExclusive ( self . mutex)
78
+ #else
60
79
let err = pthread_mutex_lock ( self . mutex)
61
80
precondition ( err == 0 )
81
+ #endif
62
82
}
63
83
64
84
/// Release the lock.
65
85
///
66
86
/// Whenever possible, consider using `withLock` instead of this method and
67
87
/// `lock`, to simplify lock handling.
68
88
public func unlock( ) {
89
+ #if os(Windows)
90
+ ReleaseSRWLockExclusive ( self . mutex)
91
+ #else
69
92
let err = pthread_mutex_unlock ( self . mutex)
70
93
precondition ( err == 0 )
94
+ #endif
71
95
}
72
96
}
73
97
@@ -102,17 +126,32 @@ extension Lock {
102
126
/// of lock is safe to use with `libpthread`-based threading models, such as the
103
127
/// one used by NIO.
104
128
internal final class ReadWriteLock {
105
- fileprivate let rwlock : UnsafeMutablePointer < pthread_rwlock_t > = UnsafeMutablePointer . allocate ( capacity: 1 )
129
+ #if os(Windows)
130
+ fileprivate let rwlock : UnsafeMutablePointer < SRWLOCK > =
131
+ UnsafeMutablePointer . allocate ( capacity: 1 )
132
+ fileprivate var shared : Bool = true
133
+ #else
134
+ fileprivate let rwlock : UnsafeMutablePointer < pthread_rwlock_t > =
135
+ UnsafeMutablePointer . allocate ( capacity: 1 )
136
+ #endif
106
137
107
138
/// Create a new lock.
108
139
public init ( ) {
140
+ #if os(Windows)
141
+ InitializeSRWLock ( self . rwlock)
142
+ #else
109
143
let err = pthread_rwlock_init ( self . rwlock, nil )
110
144
precondition ( err == 0 )
145
+ #endif
111
146
}
112
147
113
148
deinit {
149
+ #if os(Windows)
150
+ // SRWLOCK does not need to be free'd
151
+ #else
114
152
let err = pthread_rwlock_destroy ( self . rwlock)
115
153
precondition ( err == 0 )
154
+ #endif
116
155
self . rwlock. deallocate ( )
117
156
}
118
157
@@ -121,26 +160,44 @@ internal final class ReadWriteLock {
121
160
/// Whenever possible, consider using `withLock` instead of this method and
122
161
/// `unlock`, to simplify lock handling.
123
162
public func lockRead( ) {
163
+ #if os(Windows)
164
+ AcquireSRWLockShared ( self . rwlock)
165
+ self . shared = true
166
+ #else
124
167
let err = pthread_rwlock_rdlock ( self . rwlock)
125
168
precondition ( err == 0 )
169
+ #endif
126
170
}
127
171
128
172
/// Acquire a writer lock.
129
173
///
130
174
/// Whenever possible, consider using `withLock` instead of this method and
131
175
/// `unlock`, to simplify lock handling.
132
176
public func lockWrite( ) {
177
+ #if os(Windows)
178
+ AcquireSRWLockExclusive ( self . rwlock)
179
+ self . shared = true
180
+ #else
133
181
let err = pthread_rwlock_wrlock ( self . rwlock)
134
182
precondition ( err == 0 )
183
+ #endif
135
184
}
136
185
137
186
/// Release the lock.
138
187
///
139
188
/// Whenever possible, consider using `withLock` instead of this method and
140
189
/// `lock`, to simplify lock handling.
141
190
public func unlock( ) {
191
+ #if os(Windows)
192
+ if self . shared {
193
+ ReleaseSRWLockShared ( self . rwlock)
194
+ } else {
195
+ ReleaseSRWLockExclusive ( self . rwlock)
196
+ }
197
+ #else
142
198
let err = pthread_rwlock_unlock ( self . rwlock)
143
199
precondition ( err == 0 )
200
+ #endif
144
201
}
145
202
}
146
203
0 commit comments