dummy file is Option now instead of additional open

This commit is contained in:
Igor Katson 2024-08-19 11:25:45 +01:00
parent c1775e45eb
commit 60f831bc6f
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
3 changed files with 30 additions and 26 deletions

View file

@ -54,7 +54,12 @@ impl TorrentStorage for FilesystemStorage {
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
{ {
use std::os::unix::fs::FileExt; use std::os::unix::fs::FileExt;
Ok(of.file.read().read_exact_at(buf, offset)?) Ok(of
.file
.read()
.as_ref()
.context("file is None")?
.read_exact_at(buf, offset)?)
} }
#[cfg(not(target_family = "unix"))] #[cfg(not(target_family = "unix"))]
{ {
@ -70,14 +75,21 @@ impl TorrentStorage for FilesystemStorage {
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
{ {
use std::os::unix::fs::FileExt; use std::os::unix::fs::FileExt;
Ok(of.file.read().write_all_at(buf, offset)?) Ok(of
.file
.read()
.as_ref()
.context("file is None")?
.write_all_at(buf, offset)?)
} }
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
{ {
use std::os::windows::fs::FileExt; use std::os::windows::fs::FileExt;
let mut remaining = buf.len(); let mut remaining = buf.len();
let g = of.file.read();
let f = g.as_ref().context("file is None")?;
while remaining > 0 { while remaining > 0 {
remaining -= of.file.read().seek_write(buf, offset)?; remaining -= f.seek_write(buf, offset)?;
} }
Ok(()) Ok(())
} }
@ -85,8 +97,9 @@ impl TorrentStorage for FilesystemStorage {
{ {
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write};
let mut g = of.file.write(); let mut g = of.file.write();
g.seek(SeekFrom::Start(offset))?; let mut f = g.as_ref().context("file is None")?;
Ok(g.write_all(buf)?) f.seek(SeekFrom::Start(offset))?;
Ok(f.write_all(buf)?)
} }
} }
@ -95,7 +108,12 @@ impl TorrentStorage for FilesystemStorage {
} }
fn ensure_file_length(&self, file_id: usize, len: u64) -> anyhow::Result<()> { fn ensure_file_length(&self, file_id: usize, len: u64) -> anyhow::Result<()> {
Ok(self.opened_files[file_id].file.write().set_len(len)?) Ok(self.opened_files[file_id]
.file
.write()
.as_ref()
.context("file is None")?
.set_len(len)?)
} }
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> { fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {

View file

@ -102,9 +102,10 @@ impl TorrentStorage for MmapFilesystemStorage {
let mut mmaps = Vec::new(); let mut mmaps = Vec::new();
for (idx, file) in self.fs.opened_files.iter().enumerate() { for (idx, file) in self.fs.opened_files.iter().enumerate() {
let fg = file.file.write(); let fg = file.file.write();
let fg = fg.as_ref().context("file is None")?;
fg.set_len(meta.file_infos[idx].len) fg.set_len(meta.file_infos[idx].len)
.context("mmap storage: error setting length")?; .context("mmap storage: error setting length")?;
let mmap = unsafe { MmapOptions::new().map_mut(&*fg) }.context("error mapping file")?; let mmap = unsafe { MmapOptions::new().map_mut(fg) }.context("error mapping file")?;
mmaps.push(RwLock::new(mmap)); mmaps.push(RwLock::new(mmap));
} }

View file

@ -1,37 +1,22 @@
use std::fs::File; use std::fs::File;
use anyhow::Context;
use parking_lot::RwLock; use parking_lot::RwLock;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct OpenedFile { pub(crate) struct OpenedFile {
pub file: RwLock<File>, pub file: RwLock<Option<File>>,
}
pub(crate) fn dummy_file() -> anyhow::Result<std::fs::File> {
#[cfg(target_os = "windows")]
const DEVNULL: &str = "NUL";
#[cfg(not(target_os = "windows"))]
const DEVNULL: &str = "/dev/null";
std::fs::OpenOptions::new()
.read(true)
.open(DEVNULL)
.with_context(|| format!("error opening {}", DEVNULL))
} }
impl OpenedFile { impl OpenedFile {
pub fn new(f: File) -> Self { pub fn new(f: File) -> Self {
Self { Self {
file: RwLock::new(f), file: RwLock::new(Some(f)),
} }
} }
pub fn take(&self) -> anyhow::Result<File> { pub fn take(&self) -> anyhow::Result<Option<File>> {
let mut f = self.file.write(); let mut f = self.file.write();
let dummy = dummy_file()?; Ok(f.take())
let f = std::mem::replace(&mut *f, dummy);
Ok(f)
} }
pub fn take_clone(&self) -> anyhow::Result<Self> { pub fn take_clone(&self) -> anyhow::Result<Self> {