summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-19 02:56:05 +0430
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-09-19 21:10:23 +0430
commite780ee2832bf1c6a6150a87cfe439dbe0d49d7a7 (patch)
tree43117edfd71374fa37ca44151768d439921b8b69
parent65f7e45a75c44fd0af7af6b8373999358b2ca81c (diff)
downloadserenity-e780ee2832bf1c6a6150a87cfe439dbe0d49d7a7.zip
LibWeb: Avoid introducing a reference cycle in ResourceLoader::load()
Previously we were kinda sorta resolving the reference cycle, but let's just keep the requests in a hashtable instead of relying on hard to track refcount tricks. Fixes #7314.
-rw-r--r--Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp10
-rw-r--r--Userland/Libraries/LibWeb/Loader/ResourceLoader.h2
2 files changed, 7 insertions, 5 deletions
diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp
index 312f8e6db1..54b20a2b78 100644
--- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp
+++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp
@@ -191,7 +191,8 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, con
error_callback(start_request_failure_msg, {});
return;
}
- protocol_request->on_buffered_request_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback), log_success, log_failure, request, protocol_request](bool success, auto, auto& response_headers, auto status_code, ReadonlyBytes payload) {
+ m_active_requests.set(*protocol_request);
+ protocol_request->on_buffered_request_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback), log_success, log_failure, request, &protocol_request = *protocol_request](bool success, auto, auto& response_headers, auto status_code, ReadonlyBytes payload) {
--m_pending_loads;
if (on_load_counter_change)
on_load_counter_change();
@@ -202,12 +203,11 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, con
error_callback(http_load_failure_msg, {});
return;
}
- deferred_invoke([protocol_request] {
- // Clear circular reference of `protocol_request` captured by copy
- const_cast<Protocol::Request&>(*protocol_request).on_buffered_request_finish = nullptr;
- });
success_callback(payload, response_headers, status_code);
log_success(request);
+ deferred_invoke([this, &protocol_request] {
+ m_active_requests.remove(protocol_request);
+ });
};
protocol_request->set_should_buffer_all_input(true);
protocol_request->on_certificate_requested = []() -> Protocol::Request::CertificateAndKey {
diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.h b/Userland/Libraries/LibWeb/Loader/ResourceLoader.h
index 062a7917dc..0e2ffeec72 100644
--- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.h
+++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.h
@@ -13,6 +13,7 @@
namespace Protocol {
class RequestClient;
+class Request;
}
namespace Web {
@@ -53,6 +54,7 @@ private:
int m_pending_loads { 0 };
+ HashTable<NonnullRefPtr<Protocol::Request>> m_active_requests;
RefPtr<Protocol::RequestClient> m_protocol_client;
String m_user_agent;
};