diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-09-19 02:56:05 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-09-19 21:10:23 +0430 |
commit | e780ee2832bf1c6a6150a87cfe439dbe0d49d7a7 (patch) | |
tree | 43117edfd71374fa37ca44151768d439921b8b69 | |
parent | 65f7e45a75c44fd0af7af6b8373999358b2ca81c (diff) | |
download | serenity-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.cpp | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Loader/ResourceLoader.h | 2 |
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; }; |