Bug 1558215 - Refactor nsPIDOMWindowInner::AddAfterLoadRunner to be easier to use, r=baku

Differential Revision: https://phabricator.services.mozilla.com/D34366

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Olli Pettay 2019-06-12 18:36:41 +00:00
Родитель 15529ee673
Коммит 34a4375fd1
4 изменённых файлов: 72 добавлений и 26 удалений

Просмотреть файл

@ -1052,6 +1052,8 @@ nsGlobalWindowInner::~nsGlobalWindowInner() {
nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
if (ac) ac->RemoveWindowAsListener(this);
mDeprioritizedLoadRunner.clear();
nsLayoutStatics::Release();
}
@ -2546,7 +2548,7 @@ void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) {
}
}
void nsPIDOMWindowInner::SetActiveLoadingState(bool aIsLoading) {
void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) {
if (StaticPrefs::dom_separate_event_queue_for_post_message_enabled()) {
if (!aIsLoading) {
Document* doc = GetExtantDoc();
@ -2564,15 +2566,33 @@ void nsPIDOMWindowInner::SetActiveLoadingState(bool aIsLoading) {
}
if (!aIsLoading) {
for (uint32_t i = 0; i < mAfterLoadRunners.Length(); ++i) {
NS_DispatchToCurrentThread(mAfterLoadRunners[i].forget());
while (!mDeprioritizedLoadRunner.isEmpty()) {
nsCOMPtr<nsIRunnable> runner = mDeprioritizedLoadRunner.popFirst();
NS_DispatchToCurrentThread(runner.forget());
}
mAfterLoadRunners.Clear();
}
}
void nsPIDOMWindowInner::AddAfterLoadRunner(nsIRunnable* aRunner) {
mAfterLoadRunners.AppendElement(aRunner);
nsPIDOMWindowInner* nsPIDOMWindowInner::GetWindowForDeprioritizedLoadRunner() {
Document* doc = GetExtantDoc();
if (!doc) {
return nullptr;
}
doc = doc->GetTopLevelContentDocument();
if (!doc || (doc->GetReadyStateEnum() <= Document::READYSTATE_UNINITIALIZED ||
doc->GetReadyStateEnum() >= Document::READYSTATE_COMPLETE)) {
return nullptr;
}
return doc->GetInnerWindow();
}
void nsGlobalWindowInner::AddDeprioritizedLoadRunner(nsIRunnable* aRunner) {
MOZ_ASSERT(GetWindowForDeprioritizedLoadRunner() == this);
RefPtr<DeprioritizedLoadRunner> runner = new DeprioritizedLoadRunner(aRunner);
mDeprioritizedLoadRunner.insertBack(runner);
NS_DispatchToCurrentThreadQueue(runner.forget(), 5000,
EventQueuePriority::Idle);
}
// nsISpeechSynthesisGetter

Просмотреть файл

@ -58,6 +58,7 @@
#include "mozilla/dom/ImageBitmapSource.h"
#include "mozilla/UniquePtr.h"
#include "nsRefreshDriver.h"
#include "nsThreadUtils.h"
class nsIArray;
class nsIBaseWindow;
@ -1226,6 +1227,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
typedef mozilla::LinkedList<RefPtr<mozilla::dom::IdleRequest>> IdleRequests;
void RemoveIdleCallback(mozilla::dom::IdleRequest* aRequest);
void SetActiveLoadingState(bool aIsLoading) override;
void AddDeprioritizedLoadRunner(nsIRunnable* aRunner) override;
protected:
// Window offline status. Checked to see if we need to fire offline event
bool mWasOffline : 1;
@ -1397,6 +1401,28 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
nsTArray<mozilla::UniquePtr<PromiseDocumentFlushedResolver>>
mDocumentFlushedResolvers;
class DeprioritizedLoadRunner
: public mozilla::Runnable,
public mozilla::LinkedListElement<DeprioritizedLoadRunner> {
public:
explicit DeprioritizedLoadRunner(nsIRunnable* aInner)
: Runnable("DeprioritizedLoadRunner"), mInner(aInner) {}
NS_IMETHOD Run() override {
if (mInner) {;
RefPtr<nsIRunnable> inner = std::move(mInner);
inner->Run();
}
return NS_OK;
}
private:
RefPtr<nsIRunnable> mInner;
};
mozilla::LinkedList<DeprioritizedLoadRunner> mDeprioritizedLoadRunner;
static InnerWindowByIdTable* sInnerWindowsById;
// Members in the mChromeFields member should only be used in chrome windows.

Просмотреть файл

@ -175,8 +175,17 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
inline bool IsHandlingResizeEvent() const;
// Note: not related to IsLoading. Set to false if there's an error, etc.
void SetActiveLoadingState(bool aIsActiveLoading);
void AddAfterLoadRunner(nsIRunnable* aRunner);
virtual void SetActiveLoadingState(bool aIsActiveLoading) = 0;
nsPIDOMWindowInner* GetWindowForDeprioritizedLoadRunner();
/**
* The runnable will be called once there is idle time, or the top level
* page has been loaded or if a timeout has fired.
* Must be called only on the top level window, the one
* GetWindowForDeprioritizedLoadRunner returns.
*/
virtual void AddDeprioritizedLoadRunner(nsIRunnable* aRunner) = 0;
bool AddAudioContext(mozilla::dom::AudioContext* aAudioContext);
void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext);
@ -677,8 +686,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
// This will be non-null during the full lifetime of the window, initialized
// during SetNewDocument, and cleared during FreeInnerObjects.
RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
nsTArray<nsCOMPtr<nsIRunnable>> mAfterLoadRunners;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)

Просмотреть файл

@ -2255,22 +2255,15 @@ void XMLHttpRequestMainThread::ChangeStateToDone(bool aWasSync) {
mChannel->GetLoadFlags(&loadFlags);
if (loadFlags & nsIRequest::LOAD_BACKGROUND) {
nsPIDOMWindowInner* owner = GetOwner();
Document* doc = owner ? owner->GetExtantDoc() : nullptr;
doc = doc ? doc->GetTopLevelContentDocument() : nullptr;
if (doc &&
(doc->GetReadyStateEnum() > Document::READYSTATE_UNINITIALIZED &&
doc->GetReadyStateEnum() < Document::READYSTATE_COMPLETE)) {
nsPIDOMWindowInner* topWin = doc->GetInnerWindow();
if (topWin) {
MOZ_ASSERT(!mDelayedDoneNotifier);
RefPtr<XMLHttpRequestDoneNotifier> notifier =
new XMLHttpRequestDoneNotifier(this);
mDelayedDoneNotifier = notifier;
topWin->AddAfterLoadRunner(notifier);
NS_DispatchToCurrentThreadQueue(notifier.forget(), 5000,
EventQueuePriority::Idle);
return;
}
nsPIDOMWindowInner* topWin =
owner ? owner->GetWindowForDeprioritizedLoadRunner() : nullptr;
if (topWin) {
MOZ_ASSERT(!mDelayedDoneNotifier);
RefPtr<XMLHttpRequestDoneNotifier> notifier =
new XMLHttpRequestDoneNotifier(this);
mDelayedDoneNotifier = notifier;
topWin->AddDeprioritizedLoadRunner(notifier);
return;
}
}
}