Bug 364315 - Fix threadsafety assertions and crashes by only releasing documents on the main thread and not starting two speculative parsers for the same nsParser. r+sr=jst

This commit is contained in:
Blake Kaplan 2008-10-01 17:09:21 -07:00
parent a1df483e98
commit edc2d9445e

View File

@ -210,6 +210,8 @@ public:
}
~nsSpeculativeScriptThread() {
NS_ASSERTION(NS_IsMainThread() || !mDocument,
"Destroying the document on the wrong thread");
}
NS_DECL_ISUPPORTS
@ -510,9 +512,16 @@ nsSpeculativeScriptThread::StopParsing(PRBool aFromDocWrite)
}
}
// The thread is now idle. It is now safe to touch mContext on the main
// thread.
if (!mTerminated && mNumURIs) {
// The thread is now idle.
if (mTerminated) {
// If we're terminated, then we need to ensure that we release our document
// and tokenizer here on the main thread so that our last reference to them
// isn't our alter-ego rescheduled on another thread.
mDocument = nsnull;
mTokenizer = nsnull;
mScanner = nsnull;
} else if (mNumURIs) {
// Note: Don't do this if we're terminated.
nsPreloadURIs::PreloadURIs(mURIs, this);
mNumURIs = 0;
mURIs.Clear();
@ -2173,10 +2182,10 @@ nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk,
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
MOZ_TIMER_START(mParseTime);
if (mSpeculativeScriptThread) {
mSpeculativeScriptThread->StopParsing(PR_FALSE);
}
NS_ASSERTION(!mSpeculativeScriptThread || !mSpeculativeScriptThread->Parsing(),
"Bad races happening, expect to crash!");
CParserContext *originalContext = mParserContext;
result = WillBuildModel(mParserContext->mScanner->GetFilename());
if (NS_FAILED(result)) {
mFlags &= ~NS_PARSER_FLAG_CAN_TOKENIZE;
@ -2226,7 +2235,14 @@ nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk,
}
BlockParser();
SpeculativelyParse();
// If our context has changed, then someone did a document.write of
// an asynchronous script that blocked a sub context. Since *that*
// block already might have started a speculative parse, we don't
// have to.
if (mParserContext == originalContext) {
SpeculativelyParse();
}
return NS_OK;
}
if (NS_ERROR_HTMLPARSER_STOPPARSING == result) {