LibWeb: Unregister network requests *after* invoking callbacks

This ensures that the network request actually gets unreffed and deleted
at the right time.
This commit is contained in:
Andreas Kling 2024-11-11 18:05:09 +01:00 committed by Andreas Kling
parent b397a0d535
commit b3b97d2049
Notes: github-actions[bot] 2024-11-11 20:41:53 +00:00
2 changed files with 16 additions and 8 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2023, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -426,8 +426,15 @@ void ResourceLoader::load(LoadRequest& request, JS::Handle<SuccessCallback> succ
auto on_buffered_request_finished = [this, success_callback, error_callback, request, &protocol_request = *protocol_request](auto, auto const& network_error, auto& response_headers, auto status_code, auto const& reason_phrase, ReadonlyBytes payload) mutable {
handle_network_response_headers(request, response_headers);
finish_network_request(protocol_request);
// NOTE: We finish the network request *after* invoking callbacks, otherwise a nested
// event loop inside a callback may cause this function object to be destroyed
// while we're still calling it.
ScopeGuard cleanup = [&] {
deferred_invoke([this, protocol_request = NonnullRefPtr(protocol_request)] {
finish_network_request(move(protocol_request));
});
};
if (network_error.has_value() || (status_code.has_value() && *status_code >= 400 && *status_code <= 599 && (payload.is_empty() || !request.is_main_resource()))) {
StringBuilder error_builder;
if (network_error.has_value())
@ -554,15 +561,16 @@ void ResourceLoader::handle_network_response_headers(LoadRequest const& request,
}
}
void ResourceLoader::finish_network_request(NonnullRefPtr<Requests::Request> const& protocol_request)
void ResourceLoader::finish_network_request(NonnullRefPtr<Requests::Request> protocol_request)
{
--m_pending_loads;
if (on_load_counter_change)
on_load_counter_change();
Platform::EventLoopPlugin::the().deferred_invoke(JS::create_heap_function(m_heap, [this, protocol_request] {
m_active_requests.remove(protocol_request);
}));
deferred_invoke([this, protocol_request = move(protocol_request)] {
auto did_remove = m_active_requests.remove(protocol_request);
VERIFY(did_remove);
});
}
void ResourceLoader::clear_cache()

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2022, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2022, Dex <dexes.ttp@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -80,7 +80,7 @@ private:
RefPtr<Requests::Request> start_network_request(LoadRequest const&);
void handle_network_response_headers(LoadRequest const&, HTTP::HeaderMap const&);
void finish_network_request(NonnullRefPtr<Requests::Request> const&);
void finish_network_request(NonnullRefPtr<Requests::Request>);
int m_pending_loads { 0 };