Bug 1321566 Part 2: Use Disconnect pattern to manage nsPrintEngine member in nsPagePrintTimer. r=bobowen a=jcristau
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 03 Jan 2017 11:10:11 +0000
changeset 353455 873a995535164f63c126a34cb91da4095559d67c
parent 353454 9d7e7bc831d1e9114be01a5738284fd97ddf3d76
child 353456 2c312ad91c1b26a9f80cec96cfb5f05f848241d5
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbobowen, jcristau
bugs1321566
milestone52.0a2
Bug 1321566 Part 2: Use Disconnect pattern to manage nsPrintEngine member in nsPagePrintTimer. r=bobowen a=jcristau
layout/printing/nsPagePrintTimer.cpp
layout/printing/nsPagePrintTimer.h
layout/printing/nsPrintEngine.cpp
layout/printing/nsPrintEngine.h
--- a/layout/printing/nsPagePrintTimer.cpp
+++ b/layout/printing/nsPagePrintTimer.cpp
@@ -81,35 +81,37 @@ nsPagePrintTimer::Run()
   bool initNewTimer = true;
   // Check to see if we are done
   // inRange will be true if a page is actually printed
   bool inRange;
   bool donePrinting;
 
   // donePrinting will be true if it completed successfully or
   // if the printing was cancelled
-  donePrinting = mPrintEngine->PrintPage(mPrintObj, inRange);
+  donePrinting = !mPrintEngine || mPrintEngine->PrintPage(mPrintObj, inRange);
   if (donePrinting) {
     // now clean up print or print the next webshell
-    if (mPrintEngine->DonePrintingPages(mPrintObj, NS_OK)) {
+    if (!mPrintEngine || mPrintEngine->DonePrintingPages(mPrintObj, NS_OK)) {
       initNewTimer = false;
       mDone = true;
     }
   }
 
   // Note that the Stop() destroys this after the print job finishes
   // (The PrintEngine stops holding a reference when DonePrintingPages
   // returns true.)
   Stop(); 
   if (initNewTimer) {
     ++mFiringCount;
     nsresult result = StartTimer(inRange);
     if (NS_FAILED(result)) {
       mDone = true;     // had a failure.. we are finished..
-      mPrintEngine->SetIsPrinting(false);
+      if (mPrintEngine) {
+        mPrintEngine->SetIsPrinting(false);
+      }
     }
   }
   return NS_OK;
 }
 
 // nsITimerCallback
 NS_IMETHODIMP
 nsPagePrintTimer::Notify(nsITimer *timer)
@@ -144,17 +146,20 @@ nsPagePrintTimer::Notify(nsITimer *timer
     mWatchDogCount++;
     if (mWatchDogCount > WATCH_DOG_MAX_COUNT) {
       Fail();
       return NS_OK;
     }
   }
 
   if (mDocViewerPrint) {
-    bool donePrePrint = mPrintEngine->PrePrintPage();
+    bool donePrePrint = true;
+    if (mPrintEngine) {
+      donePrePrint = mPrintEngine->PrePrintPage();
+    }
 
     if (donePrePrint && !mWaitingForRemotePrint) {
       StopWatchDogTimer();
       NS_DispatchToMainThread(this);
     } else {
       // Start the watch dog if we're waiting for preprint to ensure that if any
       // mozPrintCallbacks take to long we error out.
       StartWatchDogTimer();
--- a/layout/printing/nsPagePrintTimer.h
+++ b/layout/printing/nsPagePrintTimer.h
@@ -45,16 +45,18 @@ public:
 
   NS_IMETHOD Run() override;
 
   void Stop();
 
   void WaitForRemotePrint();
   void RemotePrintFinished();
 
+  void Disconnect() { mPrintEngine = nullptr; }
+
 private:
   ~nsPagePrintTimer();
 
   nsresult StartTimer(bool aUseDelay);
   nsresult StartWatchDogTimer();
   void     StopWatchDogTimer();
   void     Fail();
 
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -226,16 +226,17 @@ nsPrintEngine::nsPrintEngine() :
   mDisallowSelectionPrint(false)
 {
 }
 
 //-------------------------------------------------------
 nsPrintEngine::~nsPrintEngine()
 {
   Destroy(); // for insurance
+  DisconnectPagePrintTimer();
 }
 
 //-------------------------------------------------------
 void nsPrintEngine::Destroy()
 {
   if (mIsDestroying) {
     return;
   }
@@ -1483,17 +1484,17 @@ nsresult nsPrintEngine::DocumentReadyFor
  */
 nsresult nsPrintEngine::CleanupOnFailure(nsresult aResult, bool aIsPrinting)
 {
   PR_PL(("****  Failed %s - rv 0x%X", aIsPrinting?"Printing":"Print Preview", aResult));
 
   /* cleanup... */
   if (mPagePrintTimer) {
     mPagePrintTimer->Stop();
-    NS_RELEASE(mPagePrintTimer);
+    DisconnectPagePrintTimer();
   }
   
   if (aIsPrinting) {
     SetIsPrinting(false);
   } else {
     SetIsPrintPreview(false);
     SetIsCreatingPrintPreview(false);
   }
@@ -3051,17 +3052,17 @@ nsPrintEngine::DonePrintingPages(nsPrint
     FirePrintCompletionEvent();
   }
 
   TurnScriptingOn(true);
   SetIsPrinting(false);
 
   // Release reference to mPagePrintTimer; the timer object destroys itself
   // after this returns true
-  NS_IF_RELEASE(mPagePrintTimer);
+  DisconnectPagePrintTimer();
 
   return true;
 }
 
 //-------------------------------------------------------
 // Recursively sets the PO items to be printed "As Is"
 // from the given item down into the tree
 void
@@ -3534,16 +3535,25 @@ private:
 void
 nsPrintEngine::FirePrintCompletionEvent()
 {
   nsCOMPtr<nsIRunnable> event = new nsPrintCompletionEvent(mDocViewerPrint);
   if (NS_FAILED(NS_DispatchToCurrentThread(event)))
     NS_WARNING("failed to dispatch print completion event");
 }
 
+void
+nsPrintEngine::DisconnectPagePrintTimer()
+{
+  if (mPagePrintTimer) {
+    mPagePrintTimer->Disconnect();
+    NS_RELEASE(mPagePrintTimer);
+  }
+}
+
 //---------------------------------------------------------------
 //---------------------------------------------------------------
 //-- Debug helper routines
 //---------------------------------------------------------------
 //---------------------------------------------------------------
 #if defined(XP_WIN) && defined(EXTENDED_DEBUG_PRINTING)
 #include "windows.h"
 #include "process.h"
--- a/layout/printing/nsPrintEngine.h
+++ b/layout/printing/nsPrintEngine.h
@@ -243,16 +243,18 @@ protected:
                                            nsRect&               aEndRect);
 
   static void MapContentForPO(nsPrintObject* aPO, nsIContent* aContent);
 
   static void MapContentToWebShells(nsPrintObject* aRootPO, nsPrintObject* aPO);
 
   static void SetPrintAsIs(nsPrintObject* aPO, bool aAsIs = true);
 
+  void DisconnectPagePrintTimer();
+
   // Static member variables
   bool mIsCreatingPrintPreview;
   bool mIsDoingPrinting;
   bool mIsDoingPrintPreview; // per DocumentViewer
   bool mProgressDialogIsShown;
 
   nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
   nsWeakPtr               mContainer;