mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibWeb: Change SessionHistoryTraversalQueue to use Promises
If multiple cross-document navigations are queued on SessionHistoryTraversalQueue, running the next entry before the current document load is finished may result in a deadlock. If the new document has a navigable element of its own, it will append steps to SHTQ and hang in nested spin_until. This change uses promises to ensure that the current document loads before the next entry is executed. Fixes timeouts in the imported tests. Co-authored-by: Sam Atkins <sam@ladybird.org>
This commit is contained in:
committed by
Alexander Kalenik
parent
eed4dd3745
commit
50a79c6af8
Notes:
github-actions[bot]
2025-11-26 11:28:29 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/50a79c6af80 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6929
@@ -403,8 +403,12 @@ Messages::WebDriverClient::BackResponse WebDriverConnection::back()
|
||||
// 7. If the previous step completed results in a pageHide event firing, wait until pageShow event fires or
|
||||
// timer' timeout fired flag to be set, whichever occurs first.
|
||||
current_top_level_browsing_context()->top_level_traversable()->append_session_history_traversal_steps(GC::create_function(realm.heap(), [this, timer, on_complete]() {
|
||||
if (timer->is_timed_out())
|
||||
return;
|
||||
// NB: Use Core::Promise to signal SessionHistoryTraversalQueue that it can continue to execute next entry.
|
||||
auto signal_to_continue_session_history_processing = Core::Promise<Empty>::construct();
|
||||
if (timer->is_timed_out()) {
|
||||
signal_to_continue_session_history_processing->resolve({});
|
||||
return signal_to_continue_session_history_processing;
|
||||
}
|
||||
|
||||
if (auto* document = current_top_level_browsing_context()->active_document(); document->page_showing()) {
|
||||
on_complete->function()();
|
||||
@@ -416,6 +420,9 @@ Messages::WebDriverClient::BackResponse WebDriverConnection::back()
|
||||
on_complete->function()();
|
||||
});
|
||||
}
|
||||
|
||||
signal_to_continue_session_history_processing->resolve({});
|
||||
return signal_to_continue_session_history_processing;
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -473,8 +480,12 @@ Messages::WebDriverClient::ForwardResponse WebDriverConnection::forward()
|
||||
// 7. If the previous step completed results in a pageHide event firing, wait until pageShow event fires or
|
||||
// timer' timeout fired flag to be set, whichever occurs first.
|
||||
current_top_level_browsing_context()->top_level_traversable()->append_session_history_traversal_steps(GC::create_function(realm.heap(), [this, timer, on_complete]() {
|
||||
if (timer->is_timed_out())
|
||||
return;
|
||||
// NB: Use Core::Promise to signal SessionHistoryTraversalQueue that it can continue to execute next entry.
|
||||
auto signal_to_continue_session_history_processing = Core::Promise<Empty>::construct();
|
||||
if (timer->is_timed_out()) {
|
||||
signal_to_continue_session_history_processing->resolve({});
|
||||
return signal_to_continue_session_history_processing;
|
||||
}
|
||||
|
||||
if (auto* document = current_top_level_browsing_context()->active_document(); document->page_showing()) {
|
||||
on_complete->function()();
|
||||
@@ -486,6 +497,9 @@ Messages::WebDriverClient::ForwardResponse WebDriverConnection::forward()
|
||||
on_complete->function()();
|
||||
});
|
||||
}
|
||||
|
||||
signal_to_continue_session_history_processing->resolve({});
|
||||
return signal_to_continue_session_history_processing;
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user