Skip to content

Commit d820345

Browse files
spevansparkera
authored andcommitted
NSCondition fixes: Ensure correct use of lock()/action/unlock() sequence (#1613)
1 parent 4c3ca09 commit d820345

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
@@ -242,8 +242,8 @@ open class Process: NSObject {
242242

243243
self.processLaunchedCondition.lock()
244244
defer {
245-
self.processLaunchedCondition.unlock()
246245
self.processLaunchedCondition.broadcast()
246+
self.processLaunchedCondition.unlock()
247247
}
248248

249249
// Dispatch the manager thread if it isn't already running

TestFoundation/TestNSLock.swift

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

6969
for t in 0..<threadCount {
7070
let thread = Thread() {
71+
condition.lock()
7172
arrayLock.lock()
7273
threadsStarted[t] = true
7374
arrayLock.unlock()
7475

75-
condition.lock()
7676
condition.wait()
7777
condition.unlock()
7878
for _ in 1...50 {
79-
let r = (endSeconds * drand48()) / 50
79+
let r = Double.random(in: 0...0.02)
8080
Thread.sleep(forTimeInterval: r)
8181
if lock.lock(before: endTime) {
8282
lock.unlock()

TestFoundation/TestThread.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class TestThread : XCTestCase {
4545
}
4646
thread.start()
4747

48-
let ok = condition.wait(until: Date(timeIntervalSinceNow: 10))
48+
let ok = condition.wait(until: Date(timeIntervalSinceNow: 2))
4949
condition.unlock()
5050
XCTAssertTrue(ok, "NSCondition wait timed out")
5151
}

0 commit comments

Comments
 (0)