mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Prevents simultaneous database access from multiple AltStores
AltStore now sends a “WillAccessDatabase” notification before loading the persistent store, which causes other AltStore instances in memory to exit (either immediately, or upon returning to foreground). This prevents multiple AltStore instances from simultaneously accessing the same database, which could result in corrupted data (especially if they used different database model versions).
This commit is contained in:
committed by
Joseph Mattello
parent
6d35a7a4ba
commit
14bd58e741
@@ -11,6 +11,15 @@ import CoreData
|
||||
import AltSign
|
||||
import Roxas
|
||||
|
||||
extension CFNotificationName
|
||||
{
|
||||
fileprivate static let willAccessDatabase = CFNotificationName("com.rileytestut.AltStore.WillAccessDatabase" as CFString)
|
||||
}
|
||||
|
||||
private let ReceivedWillAccessDatabaseNotification: @convention(c) (CFNotificationCenter?, UnsafeMutableRawPointer?, CFNotificationName?, UnsafeRawPointer?, CFDictionary?) -> Void = { (center, observer, name, object, userInfo) in
|
||||
DatabaseManager.shared.receivedWillAccessDatabaseNotification()
|
||||
}
|
||||
|
||||
fileprivate class PersistentContainer: RSTPersistentContainer
|
||||
{
|
||||
override class func defaultDirectoryURL() -> URL
|
||||
@@ -43,10 +52,15 @@ public class DatabaseManager
|
||||
private let coordinator = NSFileCoordinator()
|
||||
private let coordinatorQueue = OperationQueue()
|
||||
|
||||
private var ignoreWillAccessDatabaseNotification = false
|
||||
|
||||
private init()
|
||||
{
|
||||
self.persistentContainer = PersistentContainer(name: "AltStore", bundle: Bundle(for: DatabaseManager.self))
|
||||
self.persistentContainer.preferredMergePolicy = MergePolicy()
|
||||
|
||||
let observer = Unmanaged.passUnretained(self).toOpaque()
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer, ReceivedWillAccessDatabaseNotification, CFNotificationName.willAccessDatabase.rawValue, nil, .deliverImmediately)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +87,10 @@ public extension DatabaseManager
|
||||
|
||||
guard !self.isStarted else { return finish(nil) }
|
||||
|
||||
// Quit any other running AltStore processes to prevent concurrent database access during and after migration.
|
||||
self.ignoreWillAccessDatabaseNotification = true
|
||||
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), .willAccessDatabase, nil, nil, true)
|
||||
|
||||
self.migrateDatabaseToAppGroupIfNeeded { (result) in
|
||||
switch result
|
||||
{
|
||||
@@ -398,4 +416,14 @@ private extension DatabaseManager
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func receivedWillAccessDatabaseNotification()
|
||||
{
|
||||
defer { self.ignoreWillAccessDatabaseNotification = false }
|
||||
|
||||
// Ignore notifications sent by the current process.
|
||||
guard !self.ignoreWillAccessDatabaseNotification else { return }
|
||||
|
||||
exit(104)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user