diff --git a/crates/librqbit/src/storage/filesystem/fs.rs b/crates/librqbit/src/storage/filesystem/fs.rs index 36e57ab..6232aa9 100644 --- a/crates/librqbit/src/storage/filesystem/fs.rs +++ b/crates/librqbit/src/storage/filesystem/fs.rs @@ -1,9 +1,14 @@ use std::{ fs::OpenOptions, - io::{Read, Seek, SeekFrom, Write}, path::{Path, PathBuf}, }; +#[cfg(not(target_family = "unix"))] +use std::io::{Read, Seek, SeekFrom, Write}; + +#[cfg(target_family = "unix")] +use std::os::unix::fs::FileExt; + use anyhow::Context; use crate::{storage::StorageFactoryExt, torrent_state::ManagedTorrentInfo}; @@ -85,25 +90,31 @@ impl FilesystemStorage { impl TorrentStorage for FilesystemStorage { fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> { - let mut g = self - .opened_files - .get(file_id) - .context("no such file")? - .file - .lock(); - g.seek(SeekFrom::Start(offset))?; - Ok(g.read_exact(buf)?) + let of = self.opened_files.get(file_id).context("no such file")?; + #[cfg(target_family = "unix")] + { + Ok(of.file.read().read_exact_at(buf, offset)?) + } + #[cfg(not(target_family = "unix"))] + { + let mut g = of.file.write(); + g.seek(SeekFrom::Start(offset))?; + Ok(g.read_exact(buf)?) + } } fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> { - let mut g = self - .opened_files - .get(file_id) - .context("no such file")? - .file - .lock(); - g.seek(SeekFrom::Start(offset))?; - Ok(g.write_all(buf)?) + let of = self.opened_files.get(file_id).context("no such file")?; + #[cfg(target_family = "unix")] + { + Ok(of.file.read().write_all_at(buf, offset)?) + } + #[cfg(not(target_family = "unix"))] + { + let mut g = of.file.write(); + g.seek(SeekFrom::Start(offset))?; + Ok(g.write_all(buf)?) + } } fn remove_file(&self, _file_id: usize, filename: &Path) -> anyhow::Result<()> { @@ -111,7 +122,7 @@ impl TorrentStorage for FilesystemStorage { } fn ensure_file_length(&self, file_id: usize, len: u64) -> anyhow::Result<()> { - Ok(self.opened_files[file_id].file.lock().set_len(len)?) + Ok(self.opened_files[file_id].file.write().set_len(len)?) } fn take(&self) -> anyhow::Result> { diff --git a/crates/librqbit/src/storage/filesystem/mmap.rs b/crates/librqbit/src/storage/filesystem/mmap.rs index 731db70..e5ef44a 100644 --- a/crates/librqbit/src/storage/filesystem/mmap.rs +++ b/crates/librqbit/src/storage/filesystem/mmap.rs @@ -26,7 +26,7 @@ impl StorageFactory for MmapFilesystemStorageFactory { let fs_storage = FilesystemStorageFactory::default().init_storage(meta)?; let mut mmaps = Vec::new(); for file in fs_storage.opened_files.iter() { - let mmap = unsafe { MmapOptions::new().map_mut(&*file.file.lock()) } + let mmap = unsafe { MmapOptions::new().map_mut(&*file.file.read()) } .context("error mapping file")?; mmaps.push(RwLock::new(mmap)); } diff --git a/crates/librqbit/src/storage/filesystem/opened_file.rs b/crates/librqbit/src/storage/filesystem/opened_file.rs index b7a3cca..88f24dd 100644 --- a/crates/librqbit/src/storage/filesystem/opened_file.rs +++ b/crates/librqbit/src/storage/filesystem/opened_file.rs @@ -1,11 +1,11 @@ use std::fs::File; use anyhow::Context; -use parking_lot::Mutex; +use parking_lot::RwLock; #[derive(Debug)] pub(crate) struct OpenedFile { - pub file: Mutex, + pub file: RwLock, } pub(crate) fn dummy_file() -> anyhow::Result { @@ -23,12 +23,12 @@ pub(crate) fn dummy_file() -> anyhow::Result { impl OpenedFile { pub fn new(f: File) -> Self { Self { - file: Mutex::new(f), + file: RwLock::new(f), } } pub fn take(&self) -> anyhow::Result { - let mut f = self.file.lock(); + let mut f = self.file.write(); let dummy = dummy_file()?; let f = std::mem::replace(&mut *f, dummy); Ok(f) @@ -37,7 +37,7 @@ impl OpenedFile { pub fn take_clone(&self) -> anyhow::Result { let f = self.take()?; Ok(Self { - file: Mutex::new(f), + file: RwLock::new(f), }) } }