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 <dazabani@igalia.com>
This commit is contained in:
Delan Azabani 2025-02-20 16:31:44 +08:00 committed by GitHub
parent 7831bced76
commit 9887ad369d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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()
}