mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-08 22:33:26 +01:00
Fixes crash due to accessing AppManager.installationProgress/refreshProgress concurrently
This commit is contained in:
@@ -67,6 +67,15 @@ final class AppManager
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var progressLock: UnsafeMutablePointer<os_unfair_lock> = {
|
||||
// Can't safely pass &os_unfair_lock to os_unfair_lock functions in Swift,
|
||||
// so pass UnsafeMutablePointer instead which is guaranteed to be safe.
|
||||
// https://stackoverflow.com/a/68615042
|
||||
let lock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
|
||||
lock.initialize(to: .init())
|
||||
return lock
|
||||
}()
|
||||
|
||||
@available(iOS 13, *)
|
||||
private(set) var publisher: AppManagerPublisher {
|
||||
get { _publisher as! AppManagerPublisher }
|
||||
@@ -102,6 +111,13 @@ final class AppManager
|
||||
}
|
||||
}
|
||||
|
||||
deinit
|
||||
{
|
||||
// Should never be called, but do bookkeeping anyway.
|
||||
self.progressLock.deinitialize(count: 1)
|
||||
self.progressLock.deallocate()
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
func prepareSubscriptions()
|
||||
{
|
||||
@@ -801,12 +817,18 @@ extension AppManager
|
||||
|
||||
func installationProgress(for app: AppProtocol) -> Progress?
|
||||
{
|
||||
os_unfair_lock_lock(self.progressLock)
|
||||
defer { os_unfair_lock_unlock(self.progressLock) }
|
||||
|
||||
let progress = self.installationProgress[app.bundleIdentifier]
|
||||
return progress
|
||||
}
|
||||
|
||||
func refreshProgress(for app: AppProtocol) -> Progress?
|
||||
{
|
||||
os_unfair_lock_lock(self.progressLock)
|
||||
defer { os_unfair_lock_unlock(self.progressLock) }
|
||||
|
||||
let progress = self.refreshProgress[app.bundleIdentifier]
|
||||
return progress
|
||||
}
|
||||
@@ -2092,6 +2114,9 @@ private extension AppManager
|
||||
|
||||
func progress(for operation: AppOperation) -> Progress?
|
||||
{
|
||||
os_unfair_lock_lock(self.progressLock)
|
||||
defer { os_unfair_lock_unlock(self.progressLock) }
|
||||
|
||||
switch operation
|
||||
{
|
||||
case .install, .update: return self.installationProgress[operation.bundleIdentifier]
|
||||
@@ -2101,6 +2126,9 @@ private extension AppManager
|
||||
|
||||
func set(_ progress: Progress?, for operation: AppOperation)
|
||||
{
|
||||
os_unfair_lock_lock(self.progressLock)
|
||||
defer { os_unfair_lock_unlock(self.progressLock) }
|
||||
|
||||
switch operation
|
||||
{
|
||||
case .install, .update: self.installationProgress[operation.bundleIdentifier] = progress
|
||||
|
||||
Reference in New Issue
Block a user