mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-15 09:43:34 +01:00
[AltServer] Fixes potential crash due to race condition when device is disconnected
Simultaneously updating WiredConnectionHandler.notificationConnections can cause a crash, so we enforce serial access to notificationConnections via DispatchQueue.
This commit is contained in:
@@ -14,6 +14,7 @@ class WiredConnectionHandler: ConnectionHandler
|
|||||||
var disconnectionHandler: ((Connection) -> Void)?
|
var disconnectionHandler: ((Connection) -> Void)?
|
||||||
|
|
||||||
private var notificationConnections = [ALTDevice: NotificationConnection]()
|
private var notificationConnections = [ALTDevice: NotificationConnection]()
|
||||||
|
private let queue = DispatchQueue(label: "WiredConnectionHandler", autoreleaseFrequency: .workItem, target: .global(qos: .utility))
|
||||||
|
|
||||||
func startListening()
|
func startListening()
|
||||||
{
|
{
|
||||||
@@ -32,29 +33,35 @@ private extension WiredConnectionHandler
|
|||||||
{
|
{
|
||||||
func startNotificationConnection(to device: ALTDevice)
|
func startNotificationConnection(to device: ALTDevice)
|
||||||
{
|
{
|
||||||
ALTDeviceManager.shared.startNotificationConnection(to: device) { (connection, error) in
|
self.queue.async {
|
||||||
guard let connection = connection else { return }
|
ALTDeviceManager.shared.startNotificationConnection(to: device) { (connection, error) in
|
||||||
|
guard let connection = connection else { return }
|
||||||
|
|
||||||
let notifications: [CFNotificationName] = [.wiredServerConnectionAvailableRequest, .wiredServerConnectionStartRequest]
|
let notifications: [CFNotificationName] = [.wiredServerConnectionAvailableRequest, .wiredServerConnectionStartRequest]
|
||||||
connection.startListening(forNotifications: notifications.map { String($0.rawValue) }) { (success, error) in
|
connection.startListening(forNotifications: notifications.map { String($0.rawValue) }) { (success, error) in
|
||||||
guard success else { return }
|
guard success else { return }
|
||||||
|
|
||||||
connection.receivedNotificationHandler = { [weak self, weak connection] (notification) in
|
self.queue.async {
|
||||||
guard let self = self, let connection = connection else { return }
|
connection.receivedNotificationHandler = { [weak self, weak connection] (notification) in
|
||||||
self.handle(notification, for: connection)
|
guard let self = self, let connection = connection else { return }
|
||||||
|
self.handle(notification, for: connection)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.notificationConnections[device] = connection
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.notificationConnections[device] = connection
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func stopNotificationConnection(to device: ALTDevice)
|
func stopNotificationConnection(to device: ALTDevice)
|
||||||
{
|
{
|
||||||
guard let connection = self.notificationConnections[device] else { return }
|
self.queue.async {
|
||||||
connection.disconnect()
|
guard let connection = self.notificationConnections[device] else { return }
|
||||||
|
connection.disconnect()
|
||||||
|
|
||||||
self.notificationConnections[device] = nil
|
self.notificationConnections[device] = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handle(_ notification: CFNotificationName, for connection: NotificationConnection)
|
func handle(_ notification: CFNotificationName, for connection: NotificationConnection)
|
||||||
|
|||||||
Reference in New Issue
Block a user