mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1646776 - Move the preloader for stylesheets to SheetLoadData rather than StreamLoader. r=mayhemer
So as to make sense in a world where we can coalesce loads across documents. The per-load object is the SheetLoadData, so this way we guarantee that we fire the right events in presence of the load coalescing that the SharedStyleSheetCache does. Differential Revision: https://phabricator.services.mozilla.com/D80380
This commit is contained in:
parent
8c691e51cb
commit
e696ebbe20
@ -21,6 +21,7 @@
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/URLPreloader.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "nsITimedChannel.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsSyncLoadService.h"
|
||||
@ -412,6 +413,14 @@ SheetLoadData::AfterProcessNextEvent(nsIThreadInternal* aThread,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void SheetLoadData::PrioritizeAsPreload(nsIChannel* aChannel) {
|
||||
if (nsCOMPtr<nsISupportsPriority> sp = do_QueryInterface(aChannel)) {
|
||||
sp->AdjustPriority(nsISupportsPriority::PRIORITY_HIGHEST);
|
||||
}
|
||||
}
|
||||
|
||||
void SheetLoadData::PrioritizeAsPreload() { PrioritizeAsPreload(Channel()); }
|
||||
|
||||
void SheetLoadData::FireLoadEvent(nsIThreadInternal* aThread) {
|
||||
// First remove ourselves as a thread observer. But we need to keep
|
||||
// ourselves alive while doing that!
|
||||
@ -1239,6 +1248,9 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
|
||||
|
||||
SheetLoadDataHashKey key(aLoadData);
|
||||
mLoadsPerformed.PutEntry(key);
|
||||
|
||||
auto preloadKey = PreloadHashKey::CreateAsStyle(aLoadData);
|
||||
bool coalescedLoad = false;
|
||||
if (mSheets) {
|
||||
// If we have at least one other load ongoing, then we can defer it until
|
||||
// all non-pending loads are done.
|
||||
@ -1249,17 +1261,23 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
|
||||
mSheets->DeferSheetLoad(aLoadData);
|
||||
return NS_OK;
|
||||
}
|
||||
if (mSheets->CoalesceLoad(key, aLoadData, aSheetState)) {
|
||||
|
||||
if ((coalescedLoad = mSheets->CoalesceLoad(key, aLoadData, aSheetState))) {
|
||||
if (aSheetState == SheetState::Pending) {
|
||||
++mPendingLoadCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// All done here; once the load completes we'll be marked complete
|
||||
// automatically
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
aLoadData.NotifyOpen(preloadKey, mDocument,
|
||||
aLoadData.mIsPreload == IsPreload::FromLink);
|
||||
if (coalescedLoad) {
|
||||
// All done here; once the load completes we'll be marked complete
|
||||
// automatically.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
if (mDocument) {
|
||||
@ -1339,8 +1357,8 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
|
||||
cos->AddClassFlags(nsIClassOfService::Leader);
|
||||
}
|
||||
if (aLoadData.mIsPreload == IsPreload::FromLink) {
|
||||
StreamLoader::PrioritizeAsPreload(channel);
|
||||
StreamLoader::AddLoadBackgroundFlag(channel);
|
||||
SheetLoadData::PrioritizeAsPreload(channel);
|
||||
SheetLoadData::AddLoadBackgroundFlag(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1414,16 +1432,12 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, mDocument);
|
||||
}
|
||||
|
||||
auto preloadKey = PreloadHashKey::CreateAsStyle(aLoadData);
|
||||
streamLoader->NotifyOpen(preloadKey, channel, mDocument,
|
||||
aLoadData.mIsPreload == IsPreload::FromLink);
|
||||
|
||||
rv = channel->AsyncOpen(streamLoader);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG_ERROR((" Failed to create stream loader"));
|
||||
// ChannelOpenFailed makes sure that <link preload> nodes will get the
|
||||
// proper notification about not being able to load this resource.
|
||||
streamLoader->ChannelOpenFailed(rv);
|
||||
// NOTE: NotifyStop will be done in SheetComplete -> NotifyObservers.
|
||||
aLoadData.NotifyStart(channel);
|
||||
SheetComplete(aLoadData, rv);
|
||||
return rv;
|
||||
}
|
||||
@ -1497,6 +1511,7 @@ void Loader::NotifyObservers(SheetLoadData& aData, nsresult aStatus) {
|
||||
if (aData.mURI) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOngoingLoadCount);
|
||||
--mOngoingLoadCount;
|
||||
aData.NotifyStop(aStatus);
|
||||
}
|
||||
|
||||
if (aData.mMustNotify) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/css/Loader.h"
|
||||
#include "mozilla/css/SheetParsingMode.h"
|
||||
#include "mozilla/Encoding.h"
|
||||
#include "mozilla/PreloaderBase.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
@ -37,7 +38,9 @@ static_assert(eAuthorSheetFeatures == 0 && eUserSheetFeatures == 1 &&
|
||||
"sheet parsing mode constants won't fit "
|
||||
"in SheetLoadData::mParsingMode");
|
||||
|
||||
class SheetLoadData final : public nsIRunnable, public nsIThreadObserver {
|
||||
class SheetLoadData final : public PreloaderBase,
|
||||
public nsIRunnable,
|
||||
public nsIThreadObserver {
|
||||
using MediaMatched = dom::LinkStyle::MediaMatched;
|
||||
using IsAlternate = dom::LinkStyle::IsAlternate;
|
||||
using IsPreload = Loader::IsPreload;
|
||||
@ -47,6 +50,10 @@ class SheetLoadData final : public nsIRunnable, public nsIThreadObserver {
|
||||
virtual ~SheetLoadData();
|
||||
|
||||
public:
|
||||
// PreloaderBase
|
||||
static void PrioritizeAsPreload(nsIChannel* aChannel);
|
||||
void PrioritizeAsPreload() final;
|
||||
|
||||
// Data for loading a sheet linked from a document
|
||||
SheetLoadData(Loader* aLoader, const nsAString& aTitle, nsIURI* aURI,
|
||||
StyleSheet* aSheet, bool aSyncLoad, nsINode* aOwningNode,
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
@ -31,19 +30,11 @@ StreamLoader::~StreamLoader() {
|
||||
|
||||
NS_IMPL_ISUPPORTS(StreamLoader, nsIStreamListener)
|
||||
|
||||
// static
|
||||
void StreamLoader::PrioritizeAsPreload(nsIChannel* aChannel) {
|
||||
if (nsCOMPtr<nsISupportsPriority> sp = do_QueryInterface(aChannel)) {
|
||||
sp->AdjustPriority(nsISupportsPriority::PRIORITY_HIGHEST);
|
||||
}
|
||||
}
|
||||
|
||||
void StreamLoader::PrioritizeAsPreload() { PrioritizeAsPreload(Channel()); }
|
||||
|
||||
/* nsIRequestObserver implementation */
|
||||
NS_IMETHODIMP
|
||||
StreamLoader::OnStartRequest(nsIRequest* aRequest) {
|
||||
NotifyStart(aRequest);
|
||||
MOZ_ASSERT(aRequest);
|
||||
mSheetLoadData->NotifyStart(aRequest);
|
||||
|
||||
// It's kinda bad to let Web content send a number that results
|
||||
// in a potentially large allocation directly, but efficiency of
|
||||
@ -72,8 +63,6 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
|
||||
#endif
|
||||
|
||||
nsresult rv = mStatus;
|
||||
auto notifyStop = MakeScopeExit([&] { NotifyStop(aRequest, rv); });
|
||||
|
||||
// Decoded data
|
||||
nsCString utf8String;
|
||||
{
|
||||
@ -93,11 +82,6 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
|
||||
rv = mSheetLoadData->VerifySheetReadyToParse(aStatus, mBOMBytes, bytes,
|
||||
channel);
|
||||
if (rv != NS_OK_PARSE_SHEET) {
|
||||
// VerifySheetReadyToParse returns `NS_OK` when there was something wrong
|
||||
// with the script. We need to override the result so that any <link
|
||||
// preload> tags associted to this load will be notified the "error"
|
||||
// event. It's fine because this error goes no where.
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -11,31 +11,24 @@
|
||||
#include "nsString.h"
|
||||
#include "mozilla/css/SheetLoadData.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/PreloaderBase.h"
|
||||
|
||||
class nsIInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
class StreamLoader : public PreloaderBase, public nsIStreamListener {
|
||||
class StreamLoader : public nsIStreamListener {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
// PreloaderBase
|
||||
static void PrioritizeAsPreload(nsIChannel* aChannel);
|
||||
virtual void PrioritizeAsPreload() override;
|
||||
|
||||
explicit StreamLoader(SheetLoadData&);
|
||||
|
||||
void ChannelOpenFailed(nsresult rv) {
|
||||
#ifdef NIGHTLY_BUILD
|
||||
mChannelOpenFailed = true;
|
||||
#endif
|
||||
NotifyStart(Channel());
|
||||
NotifyStop(Channel(), rv);
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user