txn: do not close txn if database is already closed

This is a potential fix for some of the crash reports that have been
streaming in. They all seem to be crashing within ndb_close_txn. I
suspect this means that the transactions are trying to get closed when
ndb is already closed. Closing Ndb will close the transactions
automatically, so it looks like we might be trying to close twice.
This commit is contained in:
William Casarin
2024-01-25 12:06:35 -08:00
parent 0f307ab8d5
commit 56b1efc6f1
2 changed files with 16 additions and 5 deletions

View File

@@ -0,0 +1,8 @@
//
// MuteManager.swift
// damus
//
// Created by William Casarin on 2024-01-25.
//
import Foundation

View File

@@ -17,9 +17,11 @@ class NdbTxn<T> {
private var val: T! private var val: T!
var moved: Bool var moved: Bool
var inherited: Bool var inherited: Bool
var ndb: Ndb
init?(ndb: Ndb, with: (NdbTxn<T>) -> T = { _ in () }) { init?(ndb: Ndb, with: (NdbTxn<T>) -> T = { _ in () }) {
guard !ndb.closed else { return nil } guard !ndb.closed else { return nil }
self.ndb = ndb
#if TXNDEBUG #if TXNDEBUG
txn_count += 1 txn_count += 1
print("opening transaction \(txn_count)") print("opening transaction \(txn_count)")
@@ -41,11 +43,12 @@ class NdbTxn<T> {
self.val = with(self) self.val = with(self)
} }
private init(txn: ndb_txn, val: T) { private init(ndb: Ndb, txn: ndb_txn, val: T) {
self.txn = txn self.txn = txn
self.val = val self.val = val
self.moved = false self.moved = false
self.inherited = false self.inherited = false
self.ndb = ndb
} }
/// Only access temporarily! Do not store database references for longterm use. If it's a primitive type you /// Only access temporarily! Do not store database references for longterm use. If it's a primitive type you
@@ -56,7 +59,7 @@ class NdbTxn<T> {
} }
deinit { deinit {
if moved || inherited { if moved || inherited || ndb.closed {
return return
} }
@@ -71,14 +74,14 @@ class NdbTxn<T> {
// functor // functor
func map<Y>(_ transform: (T) -> Y) -> NdbTxn<Y> { func map<Y>(_ transform: (T) -> Y) -> NdbTxn<Y> {
self.moved = true self.moved = true
return .init(txn: self.txn, val: transform(val)) return .init(ndb: self.ndb, txn: self.txn, val: transform(val))
} }
// comonad!? // comonad!?
// useful for moving ownership of a transaction to another value // useful for moving ownership of a transaction to another value
func extend<Y>(_ with: (NdbTxn<T>) -> Y) -> NdbTxn<Y> { func extend<Y>(_ with: (NdbTxn<T>) -> Y) -> NdbTxn<Y> {
self.moved = true self.moved = true
return .init(txn: self.txn, val: with(self)) return .init(ndb: self.ndb, txn: self.txn, val: with(self))
} }
} }
@@ -101,7 +104,7 @@ extension NdbTxn where T: OptionalType {
return nil return nil
} }
self.moved = true self.moved = true
return NdbTxn<T.Wrapped>(txn: self.txn, val: unwrappedVal) return NdbTxn<T.Wrapped>(ndb: self.ndb, txn: self.txn, val: unwrappedVal)
} }
} }