From 82a83b294471ad04e2489d2c7816d5b8dcda6f6b Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Fri, 14 May 2021 18:08:22 -0400 Subject: [PATCH] Fix memory leak in `KeyedJobs` threadpool helper. --- Cargo.lock | 10 ---------- voxygen/Cargo.toml | 2 +- voxygen/src/hud/minimap.rs | 1 - voxygen/src/ui/mod.rs | 28 +++++++++++++++++----------- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17d6ebc8b3..907cfb5d68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2415,15 +2415,6 @@ dependencies = [ "serde", ] -[[package]] -name = "inline_tweak" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7033e97b20277cc0d043226d1940fa7719ff08d2305d1fc7421e53066d00eb4b" -dependencies = [ - "lazy_static", -] - [[package]] name = "inotify" version = "0.7.1" @@ -5843,7 +5834,6 @@ dependencies = [ "iced_native", "iced_winit", "image", - "inline_tweak", "itertools 0.10.0", "keyboard-keynames", "lazy_static", diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index 1cd3a85aba..9f949936bc 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -104,7 +104,7 @@ treeculler = "0.2" tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] } num_cpus = "1.0" # vec_map = { version = "0.8.2" } -inline_tweak = "1.0.2" +# inline_tweak = "1.0.2" itertools = "0.10.0" crossbeam-channel = "0.5" diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 4a2fec055c..b095b96d71 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -293,7 +293,6 @@ impl VoxelMinimap { .map2(TerrainChunkSize::RECT_SIZE, |i, j| (i as u32).rem_euclid(j)) .as_(); let column = self.chunk_minimaps.get(&(cpos + coff)); - //let ceiling_offset = 8; let color: Vec4 = column .and_then( |MinimapColumn { diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index 54fac9da0e..bdf750acde 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -48,7 +48,7 @@ use conrod_core::{ }; use core::{convert::TryInto, f32, f64, ops::Range}; use graphic::TexId; -use hashbrown::{hash_map::Entry, HashMap}; +use hashbrown::{hash_map::Entry, HashMap, HashSet}; use std::{hash::Hash, time::Duration}; use tracing::{error, warn}; use vek::*; @@ -1058,17 +1058,19 @@ fn default_scissor(renderer: &Renderer) -> Aabr { pub struct KeyedJobs { tx: crossbeam_channel::Sender<(K, V)>, rx: crossbeam_channel::Receiver<(K, V)>, - buf: HashMap, + completed: HashMap, + pending: HashSet, } -impl KeyedJobs { +impl KeyedJobs { #[allow(clippy::new_without_default)] pub fn new() -> Self { let (tx, rx) = crossbeam_channel::unbounded(); Self { tx, rx, - buf: HashMap::new(), + completed: HashMap::new(), + pending: HashSet::new(), } } @@ -1079,21 +1081,25 @@ impl KeyedJobs V + Send + Sync + 'static, ) -> Option<(K, V)> { if let Some(pool) = pool { - if let Some(v) = self.buf.remove(&k) { + if let Some(v) = self.completed.remove(&k) { Some((k, v)) } else { while let Ok((k2, v)) = self.rx.try_recv() { + self.pending.remove(&k2); if k == k2 { return Some((k, v)); } else { - self.buf.insert(k2, v); + self.completed.insert(k2, v); } } - let tx = self.tx.clone(); - pool.spawn("IMAGE_PROCESSING", move || { - let v = f(&k); - let _ = tx.send((k, v)); - }); + if !self.pending.contains(&k) { + self.pending.insert(k.clone()); + let tx = self.tx.clone(); + pool.spawn("IMAGE_PROCESSING", move || { + let v = f(&k); + let _ = tx.send((k, v)); + }); + } None } } else {