Merge 'WAL: don't hold shared lock across IO operations' from Jussi Saurio

Without this change and running:
```
cd stress
while cargo run -- --nr-threads=4 -i 1000 --verbose --busy-timeout=0; do; done
```
I can produce a deadlock quite reliably.
With this change, I can't.
Even with 5 second busy timeout (the default), the run makes progress
although it is slow as hell because of the busy timeout.
Full disclosure: i couldn't figure out based on parking lot RwLock
semantics why this would fix it, so maybe it just lessens the
probability

Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #3759
This commit is contained in:
Jussi Saurio
2025-10-17 08:50:26 +03:00
committed by GitHub

View File

@@ -1322,10 +1322,12 @@ impl Wal for WalFile {
tracing::debug!("wal_sync finish");
syncing.store(false, Ordering::SeqCst);
});
let shared = self.get_shared();
let file = {
let shared = self.get_shared();
assert!(shared.enabled.load(Ordering::SeqCst), "WAL must be enabled");
shared.file.as_ref().unwrap().clone()
};
self.syncing.store(true, Ordering::SeqCst);
assert!(shared.enabled.load(Ordering::SeqCst), "WAL must be enabled");
let file = shared.file.as_ref().unwrap();
let c = file.sync(completion)?;
Ok(c)
}
@@ -1575,9 +1577,11 @@ impl Wal for WalFile {
let c = Completion::new_write_linked(cmp);
let shared = self.get_shared();
assert!(shared.enabled.load(Ordering::SeqCst), "WAL must be enabled");
let file = shared.file.as_ref().unwrap();
let file = {
let shared = self.get_shared();
assert!(shared.enabled.load(Ordering::SeqCst), "WAL must be enabled");
shared.file.as_ref().unwrap().clone()
};
let c = file.pwritev(start_off, iovecs, c)?;
Ok(c)
}