From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- netwerk/protocol/http/EarlyHintRegistrar.cpp | 130 +++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 netwerk/protocol/http/EarlyHintRegistrar.cpp (limited to 'netwerk/protocol/http/EarlyHintRegistrar.cpp') diff --git a/netwerk/protocol/http/EarlyHintRegistrar.cpp b/netwerk/protocol/http/EarlyHintRegistrar.cpp new file mode 100644 index 0000000000..d77c430819 --- /dev/null +++ b/netwerk/protocol/http/EarlyHintRegistrar.cpp @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "EarlyHintRegistrar.h" + +#include "EarlyHintPreloader.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticPtr.h" +#include "nsIObserver.h" +#include "nsIObserverService.h" +#include "nsXULAppAPI.h" + +namespace { +mozilla::StaticRefPtr gSingleton; +} // namespace + +namespace mozilla::net { + +namespace { + +class EHShutdownObserver final : public nsIObserver { + public: + EHShutdownObserver() = default; + + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + private: + ~EHShutdownObserver() = default; +}; + +NS_IMPL_ISUPPORTS(EHShutdownObserver, nsIObserver) + +NS_IMETHODIMP +EHShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + EarlyHintRegistrar::CleanUp(); + return NS_OK; +} + +} // namespace + +EarlyHintRegistrar::EarlyHintRegistrar() { + // EarlyHintRegistrar is a main-thread-only object. + // All the operations should be run on main thread. + // It should be used on chrome process only. + MOZ_ASSERT(XRE_IsParentProcess()); + MOZ_ASSERT(NS_IsMainThread()); +} + +EarlyHintRegistrar::~EarlyHintRegistrar() { MOZ_ASSERT(NS_IsMainThread()); } + +// static +void EarlyHintRegistrar::CleanUp() { + MOZ_ASSERT(NS_IsMainThread()); + + if (!gSingleton) { + return; + } + + for (auto& preloader : gSingleton->mEarlyHint) { + if (auto p = preloader.GetData()) { + // Don't delete entry from EarlyHintPreloader, because that would + // invalidate the iterator. + + p->CancelChannel(NS_ERROR_ABORT, "EarlyHintRegistrar::CleanUp"_ns, + /* aDeleteEntry */ false); + } + } + gSingleton->mEarlyHint.Clear(); +} + +// static +already_AddRefed EarlyHintRegistrar::GetOrCreate() { + MOZ_ASSERT(NS_IsMainThread()); + + if (!gSingleton) { + gSingleton = new EarlyHintRegistrar(); + nsCOMPtr obs = services::GetObserverService(); + if (NS_WARN_IF(!obs)) { + return nullptr; + } + nsCOMPtr observer = new EHShutdownObserver(); + nsresult rv = + obs->AddObserver(observer, "profile-change-net-teardown", false); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + mozilla::ClearOnShutdown(&gSingleton); + } + return do_AddRef(gSingleton); +} + +void EarlyHintRegistrar::DeleteEntry(dom::ContentParentId aCpId, + uint64_t aEarlyHintPreloaderId) { + MOZ_ASSERT(NS_IsMainThread()); + + RefPtr ehp = mEarlyHint.Get(aEarlyHintPreloaderId); + if (ehp && ehp->IsFromContentParent(aCpId)) { + mEarlyHint.Remove(aEarlyHintPreloaderId); + } +} + +void EarlyHintRegistrar::RegisterEarlyHint(uint64_t aEarlyHintPreloaderId, + EarlyHintPreloader* aEhp) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aEhp); + + mEarlyHint.InsertOrUpdate(aEarlyHintPreloaderId, RefPtr{aEhp}); +} + +bool EarlyHintRegistrar::LinkParentChannel(dom::ContentParentId aCpId, + uint64_t aEarlyHintPreloaderId, + nsIParentChannel* aParent) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aParent); + + RefPtr ehp; + bool found = mEarlyHint.Get(aEarlyHintPreloaderId, getter_AddRefs(ehp)); + if (ehp && ehp->IsFromContentParent(aCpId)) { + ehp->OnParentReady(aParent); + } + MOZ_ASSERT(ehp || !found); + return found; +} + +} // namespace mozilla::net -- cgit v1.2.3