From 9887ad369d65eb362db21c778ae5f00aad74db6c Mon Sep 17 00:00:00 2001 From: Delan Azabani Date: Thu, 20 Feb 2025 16:31:44 +0800 Subject: [PATCH] libservo: Clean up destroyed webview handles (#35547) When the embedder drops the last WebView handle, the webview is destroyed, but the weak handle in libservo never gets cleaned up. This patch adds a step to `spin_event_loop` that cleans up any weak handles that have been destroyed. In theory, checking the strong count should be more efficient than trying to upgrade each handle (only to throw away the strong handle). Signed-off-by: Delan Azabani --- components/servo/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/components/servo/lib.rs b/components/servo/lib.rs index be6c93544d7..791074bb558 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -649,6 +649,7 @@ impl Servo { self.compositor.borrow_mut().perform_updates(); self.send_new_frame_ready_messages(); + self.clean_up_destroyed_webview_handles(); if self.compositor.borrow().shutdown_state() == ShutdownState::FinishedShuttingDown { return false; @@ -672,6 +673,16 @@ impl Servo { } } + fn clean_up_destroyed_webview_handles(&self) { + // Remove any webview handles that have been destroyed and would not be upgradable. + // Note that `retain` is O(capacity) because it visits empty buckets, so it may be worth + // calling `shrink_to_fit` at some point to deal with cases where a long-running Servo + // instance goes from many open webviews to only a few. + self.webviews + .borrow_mut() + .retain(|_webview_id, webview| webview.strong_count() > 0); + } + pub fn pinch_zoom_level(&self) -> f32 { self.compositor.borrow_mut().pinch_zoom_level().get() }