Skip to content

Commit dc11b4e

Browse files
committed
NSCondition fixes: Ensure correct use of lock()/action/unlock() sequence (#1613)
1 parent 5cbca0f commit dc11b4e

File tree

4 files changed

+17
-6
lines changed

4 files changed

+17
-6
lines changed

Foundation/NSData.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,27 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
210210
} else {
211211
let session = URLSession(configuration: URLSessionConfiguration.default)
212212
let cond = NSCondition()
213+
cond.lock()
214+
213215
var resError: Error?
214216
var resData: Data?
217+
var taskFinished = false
215218
let task = session.dataTask(with: url, completionHandler: { data, response, error in
219+
cond.lock()
216220
resData = data
217221
urlResponse = response
218222
resError = error
219-
cond.broadcast()
223+
taskFinished = true
224+
cond.signal()
225+
cond.unlock()
220226
})
227+
221228
task.resume()
222-
cond.wait()
229+
while taskFinished == false {
230+
cond.wait()
231+
}
232+
cond.unlock()
233+
223234
guard let data = resData else {
224235
throw resError!
225236
}

Foundation/Process.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,8 @@ open class Process: NSObject {
484484

485485
self.processIdentifier = pid
486486

487-
self.processLaunchedCondition.unlock()
488487
self.processLaunchedCondition.broadcast()
488+
self.processLaunchedCondition.unlock()
489489
}
490490

491491
open func interrupt() { NSUnimplemented() } // Not always possible. Sends SIGINT.

TestFoundation/TestNSLock.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ class TestNSLock: XCTestCase {
7676

7777
for t in 0..<threadCount {
7878
let thread = Thread() {
79+
condition.lock()
7980
arrayLock.lock()
8081
threadsStarted[t] = true
8182
arrayLock.unlock()
8283

83-
condition.lock()
8484
condition.wait()
8585
condition.unlock()
8686
for _ in 1...50 {
87-
let r = (endSeconds * drand48()) / 50
87+
let r = Double.random(in: 0...0.02)
8888
Thread.sleep(forTimeInterval: r)
8989
if lock.lock(before: endTime) {
9090
lock.unlock()

TestFoundation/TestThread.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class TestThread : XCTestCase {
5454
}
5555
thread.start()
5656

57-
let ok = condition.wait(until: Date(timeIntervalSinceNow: 10))
57+
let ok = condition.wait(until: Date(timeIntervalSinceNow: 2))
5858
condition.unlock()
5959
XCTAssertTrue(ok, "NSCondition wait timed out")
6060
}

0 commit comments

Comments
 (0)