Fix new stealing bug (ppl_cache)

This commit is contained in:
Igor Katson 2024-05-04 23:19:36 +01:00
parent c07ebbac25
commit 3b0987ec23
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5

View file

@ -210,8 +210,6 @@ impl TorrentStateLive {
pri pri
}; };
let defer_writes = paused.info.options.disk_write_queue.is_some();
let (have_broadcast_tx, _) = tokio::sync::broadcast::channel(128); let (have_broadcast_tx, _) = tokio::sync::broadcast::channel(128);
let state = Arc::new(TorrentStateLive { let state = Arc::new(TorrentStateLive {
@ -238,13 +236,9 @@ impl TorrentStateLive {
cancellation_token, cancellation_token,
have_broadcast_tx, have_broadcast_tx,
streams: paused.streams, streams: paused.streams,
per_piece_locks: if defer_writes { per_piece_locks: (0..lengths.total_pieces())
(0..lengths.total_pieces()) .map(|_| RwLock::new(()))
.map(|_| RwLock::new(())) .collect(),
.collect()
} else {
vec![]
},
}); });
state.spawn( state.spawn(
@ -1029,12 +1023,7 @@ impl PeerHandler {
// heuristic for "too slow peer" // heuristic for "too slow peer"
if elapsed.as_secs_f64() > my_avg_time.as_secs_f64() * threshold { if elapsed.as_secs_f64() > my_avg_time.as_secs_f64() * threshold {
// If the piece is locked and someone is actively writing to disk, don't steal it. // If the piece is locked and someone is actively writing to disk, don't steal it.
if let Some(_g) = self if let Some(_g) = self.state.per_piece_locks[idx.get_usize()].try_write() {
.state
.per_piece_locks
.get(idx.get_usize())
.and_then(|l| l.try_write())
{
debug!( debug!(
"will steal piece {} from {}: elapsed time {:?}, my avg piece time: {:?}", "will steal piece {} from {}: elapsed time {:?}, my avg piece time: {:?}",
idx, piece_req.peer, elapsed, my_avg_time idx, piece_req.peer, elapsed, my_avg_time
@ -1337,6 +1326,11 @@ impl PeerHandler {
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let index = piece.index; let index = piece.index;
// If someone stole the piece by now, ignore it.
// However if they didn't, don't let them steal it while we are writing.
// So that by the time we are done writing AND if it was the last piece,
// we can actually checksum etc.
// Otherwise it might get into some weird state.
let ppl_guard = { let ppl_guard = {
let g = state.lock_read("check_steal"); let g = state.lock_read("check_steal");