Bug 553363. Don't allow being in the middle of a flush to prevent the docloader from stopping. r=bzbarsky
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
@@ -146,16 +146,17 @@ struct nsListenerInfo {
};
nsDocLoader::nsDocLoader()
: mParent(nsnull),
mListenerInfoList(8),
mIsLoadingDocument(PR_FALSE),
mIsRestoringDocument(PR_FALSE),
+ mDontFlushLayout(PR_FALSE),
mIsFlushingLayout(PR_FALSE)
{
#if defined(PR_LOGGING)
if (nsnull == gDocLoaderLog) {
gDocLoaderLog = PR_NewLogModule("DocLoader");
}
#endif /* PR_LOGGING */
@@ -320,16 +321,20 @@ nsDocLoader::Stop(void)
if (loader) {
(void) loader->Stop();
}
}
if (mLoadGroup)
rv = mLoadGroup->Cancel(NS_BINDING_ABORTED);
+ // Don't report that we're flushing layout so IsBusy returns false after a
+ // Stop call.
+ mIsFlushingLayout = PR_FALSE;
+
// Clear out mChildrenInOnload. We want to make sure to fire our
// onload at this point, and there's no issue with mChildrenInOnload
// after this, since mDocumentRequest will be null after the
// DocLoaderIsEmpty() call.
mChildrenInOnload.Clear();
// Make sure to call DocLoaderIsEmpty now so that we reset mDocumentRequest,
// etc, as needed. We could be getting into here from a subframe onload, in
@@ -741,23 +746,23 @@ void nsDocLoader::DocLoaderIsEmpty(PRBoo
if (IsBusy()) {
return;
}
NS_ASSERTION(!mIsFlushingLayout, "Someone screwed up");
// The load group for this DocumentLoader is idle. Flush layout if we need
// to.
- if (aFlushLayout) {
+ if (aFlushLayout && !mDontFlushLayout) {
nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(GetAsSupports(this));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (doc) {
- mIsFlushingLayout = PR_TRUE;
+ mDontFlushLayout = mIsFlushingLayout = PR_TRUE;
doc->FlushPendingNotifications(Flush_Layout);
- mIsFlushingLayout = PR_FALSE;
+ mDontFlushLayout = mIsFlushingLayout = PR_FALSE;
}
}
// And now check whether we're really busy; that might have changed with
// the layout flush.
if (!IsBusy()) {
// Clear out our request info hash, now that our load really is done and
// we don't need it anymore to CalculateMaxProgress().
--- a/uriloader/base/nsDocLoader.h
+++ b/uriloader/base/nsDocLoader.h
@@ -241,17 +241,23 @@ protected:
* notification is fired...
*/
PRPackedBool mIsLoadingDocument;
/* Flag to indicate that we're in the process of restoring a document. */
PRPackedBool mIsRestoringDocument;
/* Flag to indicate that we're in the process of flushing layout
- undere DocLoaderIsEmpty() */
+ under DocLoaderIsEmpty() and should not do another flush. */
+ PRPackedBool mDontFlushLayout;
+
+ /* Flag to indicate whether we should consider ourselves as currently
+ flushing layout for the purposes of IsBusy. For example, if Stop has
+ been called then IsBusy should return false even if we are still
+ flushing. */
PRPackedBool mIsFlushingLayout;
private:
// A list of kids that are in the middle of their onload calls and will let
// us know once they're done. We don't want to fire onload for "normal"
// DocLoaderIsEmpty calls (those coming from requests finishing in our
// loadgroup) unless this is empty.
nsCOMArray<nsIDocumentLoader> mChildrenInOnload;