dummy file is Option now instead of additional open
This commit is contained in:
parent
c1775e45eb
commit
60f831bc6f
3 changed files with 30 additions and 26 deletions
|
|
@ -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>> {
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue