Try to workaround #17 - windows not letting to open the file while rqbit has it
This commit is contained in:
parent
a800048b7e
commit
e1a3f86a24
2 changed files with 39 additions and 3 deletions
|
|
@ -173,10 +173,10 @@ impl TorrentManager {
|
|||
options: Option<TorrentManagerOptions>,
|
||||
) -> anyhow::Result<TorrentManagerHandle> {
|
||||
let options = options.unwrap_or_default();
|
||||
let files = {
|
||||
let (files, filenames) = {
|
||||
let mut files =
|
||||
Vec::<Arc<Mutex<File>>>::with_capacity(info.iter_file_lengths()?.count());
|
||||
|
||||
let mut filenames = Vec::new();
|
||||
for (path_bits, _) in info.iter_filenames_and_lengths()? {
|
||||
let mut full_path = out.as_ref().to_owned();
|
||||
let relative_path = path_bits
|
||||
|
|
@ -200,9 +200,10 @@ impl TorrentManager {
|
|||
.with_context(|| format!("error creating {:?}", &full_path))?;
|
||||
OpenOptions::new().read(true).write(true).open(&full_path)?
|
||||
};
|
||||
filenames.push(full_path);
|
||||
files.push(Arc::new(Mutex::new(file)))
|
||||
}
|
||||
files
|
||||
(files, filenames)
|
||||
};
|
||||
|
||||
let peer_id = options.peer_id.unwrap_or_else(generate_peer_id);
|
||||
|
|
@ -270,6 +271,7 @@ impl TorrentManager {
|
|||
info_hash,
|
||||
peer_id,
|
||||
files,
|
||||
filenames,
|
||||
chunk_tracker,
|
||||
lengths,
|
||||
initial_check_results.have_bytes,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::{
|
|||
collections::{HashMap, HashSet},
|
||||
fs::File,
|
||||
net::SocketAddr,
|
||||
path::PathBuf,
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
Arc,
|
||||
|
|
@ -232,6 +233,7 @@ pub struct TorrentState {
|
|||
info: TorrentMetaV1Info<ByteString>,
|
||||
locked: Arc<RwLock<TorrentStateLocked>>,
|
||||
files: Vec<Arc<Mutex<File>>>,
|
||||
filenames: Vec<PathBuf>,
|
||||
info_hash: Id20,
|
||||
peer_id: Id20,
|
||||
lengths: Lengths,
|
||||
|
|
@ -253,6 +255,7 @@ impl TorrentState {
|
|||
info_hash: Id20,
|
||||
peer_id: Id20,
|
||||
files: Vec<Arc<Mutex<File>>>,
|
||||
filenames: Vec<PathBuf>,
|
||||
chunk_tracker: ChunkTracker,
|
||||
lengths: Lengths,
|
||||
have_bytes: u64,
|
||||
|
|
@ -271,6 +274,7 @@ impl TorrentState {
|
|||
chunks: chunk_tracker,
|
||||
})),
|
||||
files,
|
||||
filenames,
|
||||
stats: AtomicStats {
|
||||
have: AtomicU64::new(have_bytes),
|
||||
..Default::default()
|
||||
|
|
@ -894,6 +898,35 @@ impl PeerHandler {
|
|||
}
|
||||
}
|
||||
|
||||
fn reopen_read_only(&self) -> anyhow::Result<()> {
|
||||
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))
|
||||
}
|
||||
|
||||
for (file, filename) in self.state.files.iter().zip(self.state.filenames.iter()) {
|
||||
let mut g = file.lock();
|
||||
// this should close the original file
|
||||
// putting in a block just in case to guarantee drop.
|
||||
{
|
||||
*g = dummy_file()?;
|
||||
}
|
||||
*g = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.open(filename)
|
||||
.with_context(|| format!("error re-opening {:?} readonly", filename))?;
|
||||
debug!("reopened {:?} read-only", filename);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_i_am_unchoked(&self, handle: PeerHandle) {
|
||||
debug!("we are unchoked by {}", handle);
|
||||
let mut g = self.state.locked.write();
|
||||
|
|
@ -1032,6 +1065,7 @@ impl PeerHandler {
|
|||
|
||||
if self.state.get_left_to_download() == 0 {
|
||||
self.state.finished_notify.notify_waiters();
|
||||
self.reopen_read_only()?;
|
||||
}
|
||||
|
||||
self.state.maybe_transmit_haves(chunk_info.piece_index);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue