Bug 1333990: Part 2a - Allow multiple concurrent parser blockers. r=hsivonen

MozReview-Commit-ID: DYegic0RPWL
This commit is contained in:
Kris Maglione
2017-03-15 17:31:00 -07:00
parent 77efac3cb6
commit c484ba9c97
4 changed files with 26 additions and 20 deletions

View File

@@ -45,7 +45,6 @@
using namespace mozilla;
using mozilla::dom::EncodingUtils;
#define NS_PARSER_FLAG_PARSER_ENABLED 0x00000002
#define NS_PARSER_FLAG_OBSERVERS_ENABLED 0x00000004
#define NS_PARSER_FLAG_PENDING_CONTINUE_EVENT 0x00000008
#define NS_PARSER_FLAG_FLUSH_TOKENS 0x00000020
@@ -157,8 +156,8 @@ nsParser::Initialize(bool aConstructor)
mInternalState = NS_OK;
mStreamStatus = NS_OK;
mCommand = eViewNormal;
mBlocked = 0;
mFlags = NS_PARSER_FLAG_OBSERVERS_ENABLED |
NS_PARSER_FLAG_PARSER_ENABLED |
NS_PARSER_FLAG_CAN_TOKENIZE;
mProcessingNetworkData = false;
@@ -631,7 +630,7 @@ nsParser::ContinueInterruptedParsing()
nsCOMPtr<nsIContentSink> sinkDeathGrip(mSink);
#ifdef DEBUG
if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) {
if (mBlocked) {
NS_WARNING("Don't call ContinueInterruptedParsing on a blocked parser.");
}
#endif
@@ -654,13 +653,15 @@ nsParser::ContinueInterruptedParsing()
}
/**
* Stops parsing temporarily. That's it will prevent the
* parser from building up content model.
* Stops parsing temporarily. That is, it will prevent the
* parser from building up content model while scripts
* are being loaded (either an external script from a web
* page, or any number of extension content scripts).
*/
NS_IMETHODIMP_(void)
nsParser::BlockParser()
{
mFlags &= ~NS_PARSER_FLAG_PARSER_ENABLED;
mBlocked++;
}
/**
@@ -672,10 +673,9 @@ nsParser::BlockParser()
NS_IMETHODIMP_(void)
nsParser::UnblockParser()
{
if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) {
mFlags |= NS_PARSER_FLAG_PARSER_ENABLED;
} else {
NS_WARNING("Trying to unblock an unblocked parser.");
MOZ_DIAGNOSTIC_ASSERT(mBlocked > 0);
if (MOZ_LIKELY(mBlocked > 0)) {
mBlocked--;
}
}
@@ -691,7 +691,7 @@ nsParser::ContinueInterruptedParsingAsync()
NS_IMETHODIMP_(bool)
nsParser::IsParserEnabled()
{
return (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) != 0;
return !mBlocked;
}
/**
@@ -1024,8 +1024,7 @@ nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk,
{
nsresult result = NS_OK;
if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) &&
mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
if (!mBlocked && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) {
result = WillBuildModel(mParserContext->mScanner->GetFilename());
if (NS_FAILED(result)) {
@@ -1070,7 +1069,7 @@ nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk,
// (and cache any data coming in) until the parser is re-enabled.
if (NS_ERROR_HTMLPARSER_BLOCK == result) {
mSink->WillInterrupt();
if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) {
if (!mBlocked) {
// If we were blocked by a recursive invocation, don't re-block.
BlockParser();
}