Skip to content

Commit a9f4961

Browse files
committed
Use unfair lock for closeError
1 parent 5670c09 commit a9f4961

File tree

1 file changed

+11
-13
lines changed

1 file changed

+11
-13
lines changed

FirebaseAI/Sources/Types/Internal/Live/AsyncWebSocket.swift

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,50 @@
1313
// limitations under the License.
1414

1515
import Foundation
16+
private import FirebaseCoreInternal
1617

1718
final class AsyncWebSocket: NSObject, @unchecked Sendable, URLSessionWebSocketDelegate {
1819
private let webSocketTask: URLSessionWebSocketTask
1920
private let stream: AsyncThrowingStream<URLSessionWebSocketTask.Message, Error>
2021
private let continuation: AsyncThrowingStream<URLSessionWebSocketTask.Message, Error>.Continuation
2122
private var continuationFinished = false
2223
private let continuationLock = NSLock()
23-
24-
private var _closeError: WebSocketClosedError? = nil
25-
private let closeErrorLock = NSLock()
26-
private(set) var closeError: WebSocketClosedError? {
27-
get { closeErrorLock.withLock { _closeError } }
28-
set { closeErrorLock.withLock { _closeError = newValue } }
29-
}
24+
private var closeError: UnfairLock<WebSocketClosedError?>
3025

3126
init(urlSession: URLSession = GenAIURLSession.default, urlRequest: URLRequest) {
3227
webSocketTask = urlSession.webSocketTask(with: urlRequest)
3328
(stream, continuation) = AsyncThrowingStream<URLSessionWebSocketTask.Message, Error>
3429
.makeStream()
30+
closeError = UnfairLock(nil)
3531
}
3632

3733
deinit {
38-
webSocketTask.cancel(with: .goingAway, reason: nil)
34+
disconnect()
3935
}
4036

4137
func connect() -> AsyncThrowingStream<URLSessionWebSocketTask.Message, Error> {
4238
webSocketTask.resume()
43-
closeError = nil
39+
closeError.withLock { $0 = nil }
4440
startReceiving()
4541
return stream
4642
}
4743

4844
func disconnect() {
49-
if closeError != nil { return }
45+
if closeError.value() != nil { return }
5046

5147
close(code: .goingAway, reason: nil)
5248
}
5349

5450
func send(_ message: URLSessionWebSocketTask.Message) async throws {
55-
if let closeError {
51+
if let closeError = closeError.value() {
5652
throw closeError
5753
}
5854
try await webSocketTask.send(message)
5955
}
6056

6157
private func startReceiving() {
6258
Task {
63-
while !Task.isCancelled && self.webSocketTask.isOpen && self.closeError == nil {
59+
while !Task.isCancelled && self.webSocketTask.isOpen && self.closeError.value() == nil {
6460
do {
6561
let message = try await webSocketTask.receive()
6662
continuation.yield(message)
@@ -73,7 +69,9 @@ final class AsyncWebSocket: NSObject, @unchecked Sendable, URLSessionWebSocketDe
7369

7470
private func close(code: URLSessionWebSocketTask.CloseCode, reason: Data?) {
7571
let error = WebSocketClosedError(closeCode: code, closeReason: reason)
76-
closeError = error
72+
closeError.withLock {
73+
$0 = error
74+
}
7775

7876
webSocketTask.cancel(with: code, reason: reason)
7977

0 commit comments

Comments
 (0)