Fix profile crash
This fixes a crash that would occasionally occur when visiting profiles. NdbTxn objects were being deinitialized on different threads from their initialization, causing incorrect reference count decrements in thread-local transaction dictionaries. This led to premature destruction of shared ndb_txn C objects still in use by other tasks, resulting in use-after-free crashes. The root cause is that Swift does not guarantee tasks resume on the same thread after await suspension points, while NdbTxn's init/deinit rely on thread-local storage to track inherited transaction reference counts. This means that `NdbTxn` objects cannot be used in async functions, as that may cause the garbage collector to deinitialize `NdbTxn` at the end of such function, which may be running on a different thread at that point, causing the issue explained above. The fix in this case is to eliminate the `async` version of the `NdbNoteLender.borrow` method, and update usages to utilize other available methods. Note: This is a rewrite of the fix in https://github.com/damus-io/damus/pull/3329 Note 2: This relates to the fix of an unreleased feature, so therefore no changelog is needed. Changelog-None Co-authored-by: alltheseas <64376233+alltheseas@users.noreply.github.com> Closes: https://github.com/damus-io/damus/issues/3327 Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
@@ -135,13 +135,12 @@ extension NostrNetworkManager {
|
||||
let filter = NostrFilter(kinds: [.relay_list], authors: [delegate.keypair.pubkey])
|
||||
for await noteLender in self.reader.streamIndefinitely(filters: [filter]) {
|
||||
let currentRelayListCreationDate = self.getUserCurrentRelayListCreationDate()
|
||||
try? await noteLender.borrow({ note in
|
||||
guard note.pubkey == self.delegate.keypair.pubkey else { return } // Ensure this new list was ours
|
||||
guard note.createdAt > (currentRelayListCreationDate ?? 0) else { return } // Ensure this is a newer list
|
||||
guard let relayList = try? NIP65.RelayList(event: note) else { return } // Ensure it is a valid NIP-65 list
|
||||
|
||||
try? await self.set(userRelayList: relayList) // Set the validated list
|
||||
})
|
||||
guard let note = noteLender.justGetACopy() else { continue }
|
||||
guard note.pubkey == self.delegate.keypair.pubkey else { continue } // Ensure this new list was ours
|
||||
guard note.created_at > (currentRelayListCreationDate ?? 0) else { continue } // Ensure this is a newer list
|
||||
guard let relayList = try? NIP65.RelayList(event: note) else { continue } // Ensure it is a valid NIP-65 list
|
||||
|
||||
try? await self.set(userRelayList: relayList) // Set the validated list
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user