Bug 1355746 - Part 2. Polish IdleTaskRunner and reuse it for background parsing. r=smaug

This patch is mainly to make IdleTaskRunner reusable by nsHtml5TreeOpExecutor.
The only necessary work to that purpose is to remove the dependency of
sShuttingDown, which was a static variable in nsJSEnvironment.cpp.
The idea is to have a "MayStopProcessing" as a callback for the consumer to
return sShuttingDown.

In addition to sShuttingDown, we use std::function<bool()> as the runner
main callback type.

MozReview-Commit-ID: FT2X1unSvPS
This commit is contained in:
Henry Chang
2017-07-12 09:23:15 +08:00
parent 41b3f2a1c4
commit 503780c382
4 changed files with 110 additions and 58 deletions

View File

@@ -33,6 +33,7 @@
#include "nsIHTMLDocument.h"
#include "nsIViewSourceChannel.h"
#include "xpcpublic.h"
#include "mozilla/IdleTaskRunner.h"
using namespace mozilla;
@@ -62,7 +63,7 @@ class nsHtml5ExecutorReflusher : public Runnable
};
static mozilla::LinkedList<nsHtml5TreeOpExecutor>* gBackgroundFlushList = nullptr;
static nsITimer* gFlushTimer = nullptr;
StaticRefPtr<IdleTaskRunner> gBackgroundFlushRunner;
nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
: nsHtml5DocumentBuilder(false)
@@ -86,9 +87,9 @@ nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor()
if (gBackgroundFlushList->isEmpty()) {
delete gBackgroundFlushList;
gBackgroundFlushList = nullptr;
if (gFlushTimer) {
gFlushTimer->Cancel();
NS_RELEASE(gFlushTimer);
if (gBackgroundFlushRunner) {
gBackgroundFlushRunner->Cancel();
gBackgroundFlushRunner = nullptr;
}
}
}
@@ -250,8 +251,8 @@ nsHtml5TreeOpExecutor::MarkAsBroken(nsresult aReason)
return aReason;
}
void
FlushTimerCallback(nsITimer* aTimer, void* aClosure)
static bool
BackgroundFlushCallback(TimeStamp /*aDeadline*/)
{
RefPtr<nsHtml5TreeOpExecutor> ex = gBackgroundFlushList->popFirst();
if (ex) {
@@ -260,9 +261,11 @@ FlushTimerCallback(nsITimer* aTimer, void* aClosure)
if (gBackgroundFlushList && gBackgroundFlushList->isEmpty()) {
delete gBackgroundFlushList;
gBackgroundFlushList = nullptr;
gFlushTimer->Cancel();
NS_RELEASE(gFlushTimer);
gBackgroundFlushRunner->Cancel();
gBackgroundFlushRunner = nullptr;
return true;
}
return true;
}
void
@@ -281,16 +284,17 @@ nsHtml5TreeOpExecutor::ContinueInterruptedParsingAsync()
if (!isInList()) {
gBackgroundFlushList->insertBack(this);
}
if (!gFlushTimer) {
nsCOMPtr<nsITimer> t = do_CreateInstance("@mozilla.org/timer;1");
t.swap(gFlushTimer);
// The timer value 50 should not hopefully slow down background pages too
// much, yet lets event loop to process enough between ticks.
// See bug 734015.
gFlushTimer->InitWithNamedFuncCallback(FlushTimerCallback, nullptr,
50, nsITimer::TYPE_REPEATING_SLACK,
"FlushTimerCallback");
if (gBackgroundFlushRunner) {
NS_WARNING("We've already scheduled a task for background list flush.");
return;
}
// Now we set up a repetitive idle scheduler for flushing background list.
gBackgroundFlushRunner =
IdleTaskRunner::Create(&BackgroundFlushCallback,
250, // The hard deadline: 250ms.
nsContentSink::sInteractiveParseTime / 1000, // Required budget.
true, // repeating
[]{ return false; }); // MayStopProcessing
}
}