File tree Expand file tree Collapse file tree 2 files changed +43
-0
lines changed Expand file tree Collapse file tree 2 files changed +43
-0
lines changed Original file line number Diff line number Diff line change @@ -22,6 +22,19 @@ public protocol NSLocking {
2222 func unlock( )
2323}
2424
25+ extension NSLocking {
26+ @_alwaysEmitIntoClient
27+ @_disfavoredOverload
28+ public func withLock< R> ( _ body: ( ) throws -> R ) rethrows -> R {
29+ self . lock ( )
30+ defer {
31+ self . unlock ( )
32+ }
33+
34+ return try body ( )
35+ }
36+ }
37+
2538#if os(Windows)
2639private typealias _MutexPointer = UnsafeMutablePointer < SRWLOCK >
2740private typealias _RecursiveMutexPointer = UnsafeMutablePointer < CRITICAL_SECTION >
Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ class TestNSLock: XCTestCase {
1414 ( " test_lockWait " , test_lockWait) ,
1515 ( " test_threadsAndLocks " , test_threadsAndLocks) ,
1616 ( " test_recursiveLock " , test_recursiveLock) ,
17+ ( " test_withLock " , test_withLock) ,
1718
1819 ]
1920 }
@@ -187,4 +188,33 @@ class TestNSLock: XCTestCase {
187188
188189 threadCompletedCondition. unlock ( )
189190 }
191+
192+ func test_withLock( ) {
193+ let lock = NSLock ( )
194+
195+ var counter = 0
196+ let counterIncrementPerThread = 10_000
197+
198+ let threadCount = 10
199+
200+ let threadCompletedExpectation = expectation ( description: " Expected threads to complete. " )
201+ threadCompletedExpectation. expectedFulfillmentCount = threadCount
202+
203+ for _ in 0 ..< threadCount {
204+ let thread = Thread {
205+ for _ in 0 ..< counterIncrementPerThread {
206+ lock. withLock {
207+ counter += 1
208+ }
209+ }
210+
211+ threadCompletedExpectation. fulfill ( )
212+ }
213+ thread. start ( )
214+ }
215+
216+ wait ( for: [ threadCompletedExpectation] , timeout: 10 )
217+
218+ XCTAssertEqual ( counter, counterIncrementPerThread * threadCount)
219+ }
190220}
You can’t perform that action at this time.
0 commit comments