Skip to content

Commit 3ab67ad

Browse files
authored
Merge pull request #982 from mamabusi/urlSesTaskUsingSema
2 parents d6e5c2d + a449737 commit 3ab67ad

File tree

2 files changed

+63
-22
lines changed

2 files changed

+63
-22
lines changed

Foundation/NSURLSession/NSURLSessionTask.swift

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ open class URLSessionTask : NSObject, NSCopying {
7171
}
7272
/// All operations must run on this queue.
7373
fileprivate let workQueue: DispatchQueue
74-
/// This queue is used to make public attributes thread safe. It's a
75-
/// **concurrent** queue and must be used with a barries when writing. This
76-
/// allows multiple concurrent readers or a single writer.
77-
fileprivate let taskAttributesIsolation: DispatchQueue
74+
/// Using dispatch semaphore to make public attributes thread safe.
75+
/// A semaphore is a simpler option against the usage of concurrent queue
76+
/// as the critical sections are very short.
77+
fileprivate let semaphore = DispatchSemaphore(value: 1)
7878

7979
public override init() {
8080
// Darwin Foundation oddly allows calling this initializer, even though
@@ -88,7 +88,6 @@ open class URLSessionTask : NSObject, NSCopying {
8888
originalRequest = nil
8989
body = .none
9090
workQueue = DispatchQueue(label: "URLSessionTask.notused.0")
91-
taskAttributesIsolation = DispatchQueue(label: "URLSessionTask.notused.1", attributes: DispatchQueue.Attributes.concurrent)
9291
let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
9392
_ = FileManager.default.createFile(atPath: fileName, contents: nil)
9493
self.tempFileURL = URL(fileURLWithPath: fileName)
@@ -105,7 +104,6 @@ open class URLSessionTask : NSObject, NSCopying {
105104
internal init(session: URLSession, request: URLRequest, taskIdentifier: Int, body: _Body) {
106105
self.session = session
107106
self.workQueue = session.workQueue
108-
self.taskAttributesIsolation = session.taskAttributesIsolation
109107
self.taskIdentifier = taskIdentifier
110108
self.originalRequest = request
111109
self.body = body
@@ -136,17 +134,32 @@ open class URLSessionTask : NSObject, NSCopying {
136134
/// May differ from originalRequest due to http server redirection
137135
/*@NSCopying*/ open fileprivate(set) var currentRequest: URLRequest? {
138136
get {
139-
return taskAttributesIsolation.sync { self._currentRequest }
137+
semaphore.wait()
138+
defer {
139+
semaphore.signal()
140+
}
141+
return self._currentRequest
142+
}
143+
set {
144+
semaphore.wait()
145+
self._currentRequest = newValue
146+
semaphore.signal()
140147
}
141-
//TODO: dispatch_barrier_async
142-
set { taskAttributesIsolation.async(flags: .barrier) { self._currentRequest = newValue } }
143148
}
144149
fileprivate var _currentRequest: URLRequest? = nil
145150
/*@NSCopying*/ open fileprivate(set) var response: URLResponse? {
146151
get {
147-
return taskAttributesIsolation.sync { self._response }
152+
semaphore.wait()
153+
defer {
154+
semaphore.signal()
155+
}
156+
return self._response
157+
}
158+
set {
159+
semaphore.wait()
160+
self._response = newValue
161+
semaphore.signal()
148162
}
149-
set { taskAttributesIsolation.async(flags: .barrier) { self._response = newValue } }
150163
}
151164
fileprivate var _response: URLResponse? = nil
152165

@@ -158,20 +171,35 @@ open class URLSessionTask : NSObject, NSCopying {
158171
/// Number of body bytes already received
159172
open fileprivate(set) var countOfBytesReceived: Int64 {
160173
get {
161-
return taskAttributesIsolation.sync { self._countOfBytesReceived }
174+
semaphore.wait()
175+
defer {
176+
semaphore.signal()
177+
}
178+
return self._countOfBytesReceived
179+
}
180+
set {
181+
semaphore.wait()
182+
self._countOfBytesReceived = newValue
183+
semaphore.signal()
162184
}
163-
set { taskAttributesIsolation.async(flags: .barrier) { self._countOfBytesReceived = newValue } }
164185
}
165186
fileprivate var _countOfBytesReceived: Int64 = 0
166187

167188
/// Number of body bytes already sent */
168189
open fileprivate(set) var countOfBytesSent: Int64 {
169190
get {
170-
return taskAttributesIsolation.sync { self._countOfBytesSent }
191+
semaphore.wait()
192+
defer {
193+
semaphore.signal()
194+
}
195+
return self._countOfBytesSent
196+
}
197+
set {
198+
semaphore.wait()
199+
self._countOfBytesSent = newValue
200+
semaphore.signal()
171201
}
172-
set { taskAttributesIsolation.async(flags: .barrier) { self._countOfBytesSent = newValue } }
173202
}
174-
175203
fileprivate var _countOfBytesSent: Int64 = 0
176204

177205
/// Number of body bytes we expect to send, derived from the Content-Length of the HTTP request */
@@ -207,9 +235,17 @@ open class URLSessionTask : NSObject, NSCopying {
207235
*/
208236
open var state: URLSessionTask.State {
209237
get {
210-
return taskAttributesIsolation.sync { self._state }
238+
semaphore.wait()
239+
defer {
240+
semaphore.signal()
241+
}
242+
return self._state
243+
}
244+
set {
245+
semaphore.wait()
246+
self._state = newValue
247+
semaphore.signal()
211248
}
212-
set { taskAttributesIsolation.async(flags: .barrier) { self._state = newValue } }
213249
}
214250
fileprivate var _state: URLSessionTask.State = .suspended
215251

@@ -289,10 +325,16 @@ open class URLSessionTask : NSObject, NSCopying {
289325
/// URLSessionTask.highPriority, but use is not restricted to these.
290326
open var priority: Float {
291327
get {
292-
return taskAttributesIsolation.sync { self._priority }
328+
semaphore.wait()
329+
defer {
330+
semaphore.signal()
331+
}
332+
return self._priority
293333
}
294334
set {
295-
taskAttributesIsolation.async(flags: .barrier) { self._priority = newValue }
335+
semaphore.wait()
336+
self._priority = newValue
337+
semaphore.signal()
296338
}
297339
}
298340
fileprivate var _priority: Float = URLSessionTask.defaultPriority

TestFoundation/main.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ XCTMain([
7979
testCase(TestURLRequest.allTests),
8080
testCase(TestNSURLResponse.allTests),
8181
testCase(TestNSHTTPURLResponse.allTests),
82-
//Disabling because of https://bugs.swift.org/browse/SR-4655 and https://bugs.swift.org/browse/SR-4647
83-
// testCase(TestURLSession.allTests),
82+
testCase(TestURLSession.allTests),
8483
testCase(TestNSNull.allTests),
8584
testCase(TestNSUUID.allTests),
8685
testCase(TestNSValue.allTests),

0 commit comments

Comments
 (0)