-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Racing condition between input event and page switching #38621
Description
Consider this tests
servo/tests/wpt/tests/webdriver/tests/classic/perform_actions/navigation.py
Lines 26 to 37 in b397843
| def test_key(session, inline, key_chain): | |
| session.url = inline(f""" | |
| <input onkeydown="window.location = '{inline(PAGE_CONTENT)}'"/> | |
| <script> | |
| const input = document.querySelector("input"); | |
| input.focus(); | |
| </script> | |
| """) | |
| key_chain \ | |
| .key_down("1") \ | |
| .key_up("1") \ |
After key down action is sent, servo will change the document. Unfortunately, we have no synchronization with how key up action is dispatched here.
From manual logging, what I found is that here
servo/components/script/script_thread.rs
Lines 3604 to 3609 in b397843
| fn handle_input_event(&self, pipeline_id: PipelineId, event: ConstellationInputEvent) { | |
| let Some(document) = self.documents.borrow().find_document(pipeline_id) else { | |
| warn!("Compositor event sent to closed pipeline {pipeline_id}."); | |
| return; | |
| }; | |
when we finally process the pending input, the key up will never be processed, since for its pipeline we will not call below function.
servo/components/script/script_thread.rs
Lines 1053 to 1057 in b397843
| fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) { | |
| let Some(document) = self.documents.borrow().find_document(pipeline_id) else { | |
| warn!("Processing pending compositor events for closed pipeline {pipeline_id}."); | |
| return; | |
| }; |
Because between handling the event and processing the pending input, we will mark the document as inactive due to the page being switch.