mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Backport the alleged sqlite deadlock workaround
This commit is contained in:
parent
0dca1b727d
commit
ec8870816d
@ -235,9 +235,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
let _ = try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil)
|
||||
let path = basePath + "/db_sqlite"
|
||||
|
||||
#if DEBUG
|
||||
print("Instance \(self) opening sqlite at \(path)")
|
||||
#endif
|
||||
postboxLog("Instance \(self) opening sqlite at \(path)")
|
||||
|
||||
#if DEBUG
|
||||
let exists = FileManager.default.fileExists(atPath: path)
|
||||
@ -298,7 +296,9 @@ public final class SqliteValueBox: ValueBox {
|
||||
preconditionFailure("Couldn't open database")
|
||||
}
|
||||
|
||||
sqlite3_busy_timeout(database.handle, 1000 * 10000)
|
||||
postboxLog("Did open DB at \(path)")
|
||||
|
||||
sqlite3_busy_timeout(database.handle, 5 * 1000)
|
||||
|
||||
var resultCode: Bool = true
|
||||
|
||||
@ -307,7 +307,11 @@ public final class SqliteValueBox: ValueBox {
|
||||
resultCode = database.execute("PRAGMA cipher_default_plaintext_header_size=32")
|
||||
assert(resultCode)
|
||||
|
||||
postboxLog("Did set up cipher")
|
||||
|
||||
if self.isEncrypted(database) {
|
||||
postboxLog("Database is encrypted")
|
||||
|
||||
if let encryptionParameters = encryptionParameters {
|
||||
precondition(encryptionParameters.salt.data.count == 16)
|
||||
precondition(encryptionParameters.key.data.count == 32)
|
||||
@ -317,11 +321,14 @@ public final class SqliteValueBox: ValueBox {
|
||||
resultCode = database.execute("PRAGMA key=\"x'\(hexKey)'\"")
|
||||
assert(resultCode)
|
||||
|
||||
postboxLog("Setting encryption key")
|
||||
|
||||
if self.isEncrypted(database) {
|
||||
postboxLog("Encryption key is invalid")
|
||||
|
||||
if isTemporary || isReadOnly {
|
||||
return nil
|
||||
}
|
||||
postboxLog("Encryption key is invalid")
|
||||
|
||||
for fileName in dabaseFileNames {
|
||||
let _ = try? FileManager.default.removeItem(atPath: basePath + "/\(fileName)")
|
||||
@ -354,6 +361,8 @@ public final class SqliteValueBox: ValueBox {
|
||||
assert(resultCode)
|
||||
}
|
||||
} else if let encryptionParameters = encryptionParameters, encryptionParameters.forceEncryptionIfNoSet {
|
||||
postboxLog("Not encrypted")
|
||||
|
||||
let hexKey = hexString(encryptionParameters.key.data + encryptionParameters.salt.data)
|
||||
|
||||
if FileManager.default.fileExists(atPath: path) {
|
||||
@ -410,6 +419,8 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
}
|
||||
|
||||
postboxLog("Did set up encryption")
|
||||
|
||||
//database.execute("PRAGMA cache_size=-2097152")
|
||||
resultCode = database.execute("PRAGMA mmap_size=0")
|
||||
assert(resultCode)
|
||||
@ -421,6 +432,9 @@ public final class SqliteValueBox: ValueBox {
|
||||
assert(resultCode)
|
||||
resultCode = database.execute("PRAGMA cipher_memory_security = OFF")
|
||||
assert(resultCode)
|
||||
|
||||
postboxLog("Did set up pragmas")
|
||||
|
||||
//resultCode = database.execute("PRAGMA wal_autocheckpoint=500")
|
||||
//database.execute("PRAGMA journal_size_limit=1536")
|
||||
|
||||
@ -442,8 +456,12 @@ public final class SqliteValueBox: ValueBox {
|
||||
let _ = self.runPragma(database, "checkpoint_fullfsync = 1")
|
||||
assert(self.runPragma(database, "checkpoint_fullfsync") == "1")
|
||||
|
||||
postboxLog("Did set up checkpoint_fullfsync")
|
||||
|
||||
self.beginInternal(database: database)
|
||||
|
||||
postboxLog("Did begin transaction")
|
||||
|
||||
let result = self.getUserVersion(database)
|
||||
|
||||
if result < 3 {
|
||||
@ -463,8 +481,12 @@ public final class SqliteValueBox: ValueBox {
|
||||
self.fullTextTables[table.id] = table
|
||||
}
|
||||
|
||||
postboxLog("Did load tables")
|
||||
|
||||
self.commitInternal(database: database)
|
||||
|
||||
postboxLog("Did commit final")
|
||||
|
||||
lock.unlock()
|
||||
|
||||
return database
|
||||
@ -518,7 +540,21 @@ public final class SqliteValueBox: ValueBox {
|
||||
|
||||
private func isEncrypted(_ database: Database) -> Bool {
|
||||
var statement: OpaquePointer? = nil
|
||||
postboxLog("isEncrypted prepare...")
|
||||
|
||||
let allIsOk = Atomic<Bool>(value: false)
|
||||
let databasePath = self.databasePath
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 5.0, execute: {
|
||||
if allIsOk.with({ $0 }) == false {
|
||||
postboxLog("Timeout reached, discarding database")
|
||||
try? FileManager.default.removeItem(atPath: databasePath)
|
||||
|
||||
preconditionFailure()
|
||||
}
|
||||
})
|
||||
let status = sqlite3_prepare_v2(database.handle, "SELECT * FROM sqlite_master LIMIT 1", -1, &statement, nil)
|
||||
let _ = allIsOk.swap(true)
|
||||
postboxLog("isEncrypted prepare done")
|
||||
if statement == nil {
|
||||
postboxLog("isEncrypted: sqlite3_prepare_v2 status = \(status) [\(self.databasePath)]")
|
||||
return true
|
||||
@ -536,6 +572,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
preparedStatement.destroy()
|
||||
return true
|
||||
}
|
||||
postboxLog("isEncrypted step done")
|
||||
preparedStatement.destroy()
|
||||
return status == SQLITE_NOTADB
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user