From 20f20a07f23c117a0ce2e4d230162133418b6d59 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 5 May 2025 09:44:30 +0200 Subject: [PATCH] script: Unconditionally send exit message during pipeline shutdown (#36808) If a `WebView` is dropped immediately after creating it, the exit pipeline message can arrive to the `ScriptThread` before the `Document` is created for the pipeline. If this happens, we should still send a message to the `Constellation` informing it that the pipeline is closed, otherwise it will never know that this has happened properly. Testing: This change includes a new unit test. Fixes: #36807. Signed-off-by: Martin Robinson --- components/script/script_thread.rs | 17 +++++++++-------- components/servo/tests/webview.rs | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 6e192cc920c..9f6e1bc1dd1 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2813,8 +2813,6 @@ impl ScriptThread { ) { debug!("{id}: Starting pipeline exit."); - self.closed_pipelines.borrow_mut().insert(id); - // Abort the parser, if any, // to prevent any further incoming networking messages from being handled. let document = self.documents.borrow_mut().remove(id); @@ -2835,12 +2833,6 @@ impl ScriptThread { debug!("{id}: Shutting down layout"); document.window().layout_mut().exit_now(); - debug!("{id}: Sending PipelineExited message to constellation"); - self.senders - .pipeline_to_constellation_sender - .send((id, ScriptToConstellationMessage::PipelineExited)) - .ok(); - // Clear any active animations and unroot all of the associated DOM objects. debug!("{id}: Clearing animations"); document.animations().clear(); @@ -2863,6 +2855,15 @@ impl ScriptThread { window.clear_js_runtime(); } + // Prevent any further work for this Pipeline. + self.closed_pipelines.borrow_mut().insert(id); + + debug!("{id}: Sending PipelineExited message to constellation"); + self.senders + .pipeline_to_constellation_sender + .send((id, ScriptToConstellationMessage::PipelineExited)) + .ok(); + debug!("{id}: Finished pipeline exit"); } diff --git a/components/servo/tests/webview.rs b/components/servo/tests/webview.rs index 4ed06e412da..89fbe2025a3 100644 --- a/components/servo/tests/webview.rs +++ b/components/servo/tests/webview.rs @@ -44,6 +44,18 @@ fn test_create_webview(servo_test: &ServoTest) -> Result<(), anyhow::Error> { Ok(()) } -fn main() { - run_api_tests!(test_create_webview); +fn test_create_webview_and_immediately_drop_webview_before_shutdown( + servo_test: &ServoTest, +) -> Result<(), anyhow::Error> { + WebViewBuilder::new(servo_test.servo()).build(); + Ok(()) +} + +fn main() { + run_api_tests!( + test_create_webview, + // This test needs to be last, as it tests creating and dropping + // a WebView right before shutdown. + test_create_webview_and_immediately_drop_webview_before_shutdown + ); }