mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibThreading: Resolve BackgroundAction error callback use-after-free
This change ensures that a reference to the BackgroundAction is held until after the error callback has executed on the event loop. This fixes an intermittent crash in Assistant :^)
This commit is contained in:
parent
ddec4cd7f2
commit
d1a964a43b
Notes:
sideshowbarker
2024-07-17 01:00:06 +09:00
Author: https://github.com/tcl3 Commit: https://github.com/SerenityOS/serenity/commit/d1a964a43b Pull-request: https://github.com/SerenityOS/serenity/pull/18015 Reviewed-by: https://github.com/LucasChollet ✅ Reviewed-by: https://github.com/kleinesfilmroellchen ✅
1 changed files with 7 additions and 2 deletions
|
@ -79,11 +79,13 @@ private:
|
||||||
auto result = m_action(*this);
|
auto result = m_action(*this);
|
||||||
// The event loop cancels the promise when it exits.
|
// The event loop cancels the promise when it exits.
|
||||||
m_canceled |= m_promise->is_canceled();
|
m_canceled |= m_promise->is_canceled();
|
||||||
|
auto callback_scheduled = false;
|
||||||
// All of our work was successful and we weren't cancelled; resolve the event loop's promise.
|
// All of our work was successful and we weren't cancelled; resolve the event loop's promise.
|
||||||
if (!m_canceled && !result.is_error()) {
|
if (!m_canceled && !result.is_error()) {
|
||||||
m_result = result.release_value();
|
m_result = result.release_value();
|
||||||
// If there is no completion callback, we don't rely on the user keeping around the event loop.
|
// If there is no completion callback, we don't rely on the user keeping around the event loop.
|
||||||
if (m_on_complete) {
|
if (m_on_complete) {
|
||||||
|
callback_scheduled = true;
|
||||||
origin_event_loop->deferred_invoke([this] {
|
origin_event_loop->deferred_invoke([this] {
|
||||||
// Our promise's resolution function will never error.
|
// Our promise's resolution function will never error.
|
||||||
(void)m_promise->resolve(*this);
|
(void)m_promise->resolve(*this);
|
||||||
|
@ -99,14 +101,17 @@ private:
|
||||||
|
|
||||||
m_promise->cancel(Error::from_errno(ECANCELED));
|
m_promise->cancel(Error::from_errno(ECANCELED));
|
||||||
if (m_on_error) {
|
if (m_on_error) {
|
||||||
|
callback_scheduled = true;
|
||||||
origin_event_loop->deferred_invoke([this, error = move(error)]() mutable {
|
origin_event_loop->deferred_invoke([this, error = move(error)]() mutable {
|
||||||
m_on_error(move(error));
|
m_on_error(move(error));
|
||||||
|
remove_from_parent();
|
||||||
});
|
});
|
||||||
origin_event_loop->wake();
|
origin_event_loop->wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_from_parent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!callback_scheduled)
|
||||||
|
remove_from_parent();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue