From 3c44596dc6901b288a62d67da2f0e8ee1a84d4e7 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Sat, 27 Dec 2025 13:40:12 +0100 Subject: [PATCH] fix: single file handle in `atomic_write` Uses one file handle for create/write/sync instead of separate write then reopen for sync, it just makes sense and it also avoids a race condition on Windows where the file may still be held briefly after closing which leads to Windows test failures in the CI overhaul PR #253. --- dash-spv/src/storage/io.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dash-spv/src/storage/io.rs b/dash-spv/src/storage/io.rs index 93e998b7b..9854d5ab0 100644 --- a/dash-spv/src/storage/io.rs +++ b/dash-spv/src/storage/io.rs @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf}; use crate::error::{StorageError, StorageResult}; +use tokio::io::AsyncWriteExt; /// Get the temporary file path for atomic writes. /// Uses process ID and a counter to ensure uniqueness even with concurrent writes. @@ -32,10 +33,8 @@ pub(crate) async fn atomic_write(path: &Path, data: &[u8]) -> StorageResult<()> // Write to temporary file let write_result = async { - tokio::fs::write(&temp_path, data).await?; - - // Sync to disk - open the file and call sync_all - let file = tokio::fs::File::open(&temp_path).await?; + let mut file = tokio::fs::File::create(&temp_path).await?; + file.write_all(data).await?; file.sync_all().await?; Ok::<(), std::io::Error>(())