From 4a737398711c362e220e8ab74561427bc60d82d3 Mon Sep 17 00:00:00 2001 From: Igor Katson Date: Mon, 29 Apr 2024 19:28:05 +0100 Subject: [PATCH] Force set file length on stream --- TODO.md | 3 +- .../src/torrent_state/initializing.rs | 2 +- .../librqbit/src/torrent_state/streaming.rs | 31 ++++++++++++------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/TODO.md b/TODO.md index 4641d77..705e949 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,7 @@ - [x] use some concurrent hashmap e.g. flurry or dashmap - [x] tracing instead of logging. Debugging peers: RUST_LOG=[{peer=.*}]=debug test-log for tests -- [x] reopen read only is bugged +- [x] (reopen) read only is bugged - [x] initializing/checking - [x] blocks the whole process. Need to break it up. On slower devices (rpi) just hangs for a good while - [x] checking torrents should be visible right away @@ -98,3 +98,4 @@ Other: - [ ] keepalive is useless, the tieout is 120s, and read timeout is 10s. Need to send keepalive only if nothing was done recently. - [x] url should have the filename +- [ ] reopening files: get rid of it!!! Even on Windows it should be alright - no need to reopen them. diff --git a/crates/librqbit/src/torrent_state/initializing.rs b/crates/librqbit/src/torrent_state/initializing.rs index d4c0026..453c196 100644 --- a/crates/librqbit/src/torrent_state/initializing.rs +++ b/crates/librqbit/src/torrent_state/initializing.rs @@ -1,5 +1,5 @@ use std::{ - fs::{File, OpenOptions}, + fs::OpenOptions, sync::{atomic::AtomicU64, Arc}, time::Instant, }; diff --git a/crates/librqbit/src/torrent_state/streaming.rs b/crates/librqbit/src/torrent_state/streaming.rs index bff03b5..4647037 100644 --- a/crates/librqbit/src/torrent_state/streaming.rs +++ b/crates/librqbit/src/torrent_state/streaming.rs @@ -14,7 +14,7 @@ use librqbit_core::lengths::{Lengths, ValidPieceIndex}; use tokio::io::{AsyncRead, AsyncSeek}; use tracing::{debug, trace}; -use crate::{opened_file::OpenedFile, ManagedTorrent}; +use crate::{opened_file::OpenedFile, type_aliases::OpenedFiles, ManagedTorrent}; use super::ManagedTorrentHandle; @@ -292,9 +292,9 @@ impl Drop for FileStream { } impl ManagedTorrent { - fn with_opened_file(&self, file_id: usize, f: F) -> anyhow::Result + fn with_opened_files(&self, f: F) -> anyhow::Result where - F: FnOnce(&OpenedFile) -> R, + F: FnOnce(&OpenedFiles) -> R, { self.with_state(|s| { let files = match s { @@ -302,11 +302,20 @@ impl ManagedTorrent { crate::ManagedTorrentState::Live(l) => &l.files, s => anyhow::bail!("with_opened_file: invalid state {}", s.name()), }; - let fd = files.get(file_id).context("invalid file id")?; - Ok(f(fd)) + Ok(f(files)) }) } + fn with_opened_file(&self, file_id: usize, f: F) -> anyhow::Result + where + F: FnOnce(&OpenedFile) -> R, + { + self.with_opened_files(|opened_files| { + let fd = opened_files.get(file_id).context("invalid file id")?; + Ok(f(fd)) + })? + } + fn streams(&self) -> anyhow::Result> { self.with_state(|s| match s { crate::ManagedTorrentState::Paused(p) => Ok(p.streams.clone()), @@ -343,12 +352,12 @@ impl ManagedTorrent { torrent: self, }; if s.torrent.maybe_reconnect_needed_peers_for_file(file_id) { - s.torrent.with_opened_file(file_id, |fd| { - fd.reopen(false)?; - fd.file - .lock() - .set_len(fd.len) - .context("error setting file length") + // TODO: get rid of reopening files, it's such a source of bugs and complexity + s.torrent.with_opened_files(|files| { + for file in files { + file.reopen(false)?; + } + Ok::<_, anyhow::Error>(()) })??; } streams.streams.insert(