Bug 553363. Don't allow being in the middle of a flush to prevent the docloader from stopping. r=bzbarsky
authorTimothy Nikkel <tnikkel@gmail.com>
Sat, 10 Apr 2010 13:03:40 -0500
changeset 40679 ae7c766a0fe223f8db9a9561bd61790fead133a8
parent 40678 aae8a7a454dc4cd8ef826c50567e1fe0b328d25d
child 40680 ed979b721cb79a964ee018e7426292c8b20b5c12
push idunknown
push userunknown
push dateunknown
reviewersbzbarsky
bugs553363
milestone1.9.3a5pre
Bug 553363. Don't allow being in the middle of a flush to prevent the docloader from stopping. r=bzbarsky
uriloader/base/nsDocLoader.cpp
uriloader/base/nsDocLoader.h
--- 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;