From 633e2a70a437c190b7210cc9059fe6890b871532 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 4 Apr 2024 15:32:23 -0700 Subject: [PATCH] Fix memory leak in owner (#2245) * Fix: memory leak on listeners for elements --------- Co-authored-by: Evan Almloff --- packages/core/src/events.rs | 8 +++----- packages/desktop/Cargo.toml | 2 +- packages/generational-box/src/lib.rs | 12 ++++++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index 5be005f46..0fed60f21 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -1,6 +1,5 @@ -use generational_box::{GenerationalBox, UnsyncStorage}; - -use crate::{generational_box::current_owner, global_context::current_scope_id, Runtime, ScopeId}; +use crate::{global_context::current_scope_id, Runtime, ScopeId}; +use generational_box::GenerationalBox; use std::{cell::Cell, rc::Rc}; /// A wrapper around some generic data that handles the event's state @@ -199,8 +198,7 @@ impl EventHandler { /// Create a new [`EventHandler`] from an [`FnMut`] #[track_caller] pub fn new(mut f: impl FnMut(T) + 'static) -> EventHandler { - let owner = current_owner::(); - let callback = owner.insert(Some(Box::new(move |event: T| { + let callback = GenerationalBox::leak(Some(Box::new(move |event: T| { f(event); }) as Box)); EventHandler { diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 13c85b512..da8cce399 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -70,7 +70,7 @@ core-foundation = "0.9.3" objc = "0.2.7" [features] -default = ["tokio_runtime", "wry/objc-exception", "hot-reload"] +default = ["tokio_runtime", "wry/objc-exception", "hot-reload", "devtools"] tokio_runtime = ["tokio"] fullscreen = ["wry/fullscreen"] transparent = ["wry/transparent"] diff --git a/packages/generational-box/src/lib.rs b/packages/generational-box/src/lib.rs index f73de000f..ba28c607a 100644 --- a/packages/generational-box/src/lib.rs +++ b/packages/generational-box/src/lib.rs @@ -66,6 +66,18 @@ impl Debug for GenerationalBox { } impl> GenerationalBox { + /// Create a new generational box by leaking a value into the storage. This is useful for creating + /// a box that needs to be manually dropped with no owners. + #[track_caller] + pub fn leak(value: T) -> Self { + let mut location = S::claim(); + location.replace_with_caller( + value, + #[cfg(any(debug_assertions, feature = "debug_ownership"))] + std::panic::Location::caller(), + ) + } + #[inline(always)] pub(crate) fn validate(&self) -> bool { #[cfg(any(debug_assertions, feature = "check_generation"))]