瀏覽代碼

Fix memory leak in owner (#2245)

* Fix: memory leak on listeners for elements

---------

Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
Jonathan Kelley 1 年之前
父節點
當前提交
633e2a70a4
共有 3 個文件被更改,包括 16 次插入6 次删除
  1. 3 5
      packages/core/src/events.rs
  2. 1 1
      packages/desktop/Cargo.toml
  3. 12 0
      packages/generational-box/src/lib.rs

+ 3 - 5
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<T: 'static> EventHandler<T> {
     /// Create a new [`EventHandler`] from an [`FnMut`]
     #[track_caller]
     pub fn new(mut f: impl FnMut(T) + 'static) -> EventHandler<T> {
-        let owner = current_owner::<UnsyncStorage>();
-        let callback = owner.insert(Some(Box::new(move |event: T| {
+        let callback = GenerationalBox::leak(Some(Box::new(move |event: T| {
             f(event);
         }) as Box<dyn FnMut(T)>));
         EventHandler {

+ 1 - 1
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"]

+ 12 - 0
packages/generational-box/src/lib.rs

@@ -66,6 +66,18 @@ impl<T, S: AnyStorage> Debug for GenerationalBox<T, S> {
 }
 
 impl<T, S: Storage<T>> GenerationalBox<T, S> {
+    /// 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"))]