From e5465ff8e52195d5fe1fe64819e15cca1500e4c4 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Mon, 28 Apr 2025 17:59:55 -0600 Subject: [PATCH] LibWeb: Crash less when the main thread exits while trying to render Attach a 'job' to the main thread event loop, trusting that the event loop implementation will cancel it when asked to quit. This is something that our Unix implementation does, but isn't strictly part of the contract of EventLoopImplementation. --- Libraries/LibWeb/HTML/RenderingThread.cpp | 10 ++++++++++ Libraries/LibWeb/HTML/RenderingThread.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/Libraries/LibWeb/HTML/RenderingThread.cpp b/Libraries/LibWeb/HTML/RenderingThread.cpp index 89432dc462b..71c3d64c2c9 100644 --- a/Libraries/LibWeb/HTML/RenderingThread.cpp +++ b/Libraries/LibWeb/HTML/RenderingThread.cpp @@ -13,7 +13,15 @@ namespace Web::HTML { RenderingThread::RenderingThread() : m_main_thread_event_loop(Core::EventLoop::current()) + , m_main_thread_exit_promise(Core::Promise>::construct()) { + // FIXME: Come up with a better "event loop exited" notification mechanism. + m_main_thread_exit_promise->on_rejection = [this](Error const&) -> void { + Threading::MutexLocker const locker { m_rendering_task_mutex }; + m_exit = true; + m_rendering_task_ready_wake_condition.signal(); + }; + m_main_thread_event_loop.add_job(m_main_thread_exit_promise); } RenderingThread::~RenderingThread() @@ -58,6 +66,8 @@ void RenderingThread::rendering_thread_loop() auto painting_surface = painting_surface_for_backing_store(task->backing_store); m_skia_player->execute(*task->display_list, task->scroll_state_snapshot, painting_surface); + if (m_exit) + break; m_main_thread_event_loop.deferred_invoke([callback = move(task->callback)] { callback(); }); diff --git a/Libraries/LibWeb/HTML/RenderingThread.h b/Libraries/LibWeb/HTML/RenderingThread.h index f5e0373d68f..7cb92cc61fc 100644 --- a/Libraries/LibWeb/HTML/RenderingThread.h +++ b/Libraries/LibWeb/HTML/RenderingThread.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,7 @@ private: RefPtr m_thread; Atomic m_exit { false }; + NonnullRefPtr>> m_main_thread_exit_promise; struct Task { NonnullRefPtr display_list;