author | Brendan Dahl <bdahl@mozilla.com> |
Tue, 02 Oct 2012 10:42:21 -0700 | |
changeset 108990 | fe034183d766cabe18311f5dc1f8a290f67c823a |
parent 108989 | 0ae09da96f63b1d283822be4de3f5a90e60e9ae7 |
child 108991 | 24b61485c945c35effea9278e54f8685ae9880f0 |
push id | 15793 |
push user | ryanvm@gmail.com |
push date | Wed, 03 Oct 2012 02:09:02 +0000 |
treeherder | mozilla-inbound@24b61485c945 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 789507 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/generic/nsSimplePageSequence.cpp +++ b/layout/generic/nsSimplePageSequence.cpp @@ -107,16 +107,17 @@ nsSimplePageSequenceFrame::nsSimplePageS // Doing this here so we only have to go get these formats once SetPageNumberFormat("pagenumber", "%1$d", true); SetPageNumberFormat("pageofpages", "%1$d of %2$d", false); } nsSimplePageSequenceFrame::~nsSimplePageSequenceFrame() { delete mPageData; + ResetPrintCanvasList(); } NS_QUERYFRAME_HEAD(nsSimplePageSequenceFrame) NS_QUERYFRAME_ENTRY(nsIPageSequenceFrame) NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) //----------------------------------------------------------------------
--- a/layout/printing/nsPagePrintTimer.cpp +++ b/layout/printing/nsPagePrintTimer.cpp @@ -39,16 +39,44 @@ nsPagePrintTimer::StartTimer(bool aUseDe delay = mDelay; } } mTimer->InitWithCallback(this, delay, nsITimer::TYPE_ONE_SHOT); } return result; } +nsresult +nsPagePrintTimer::StartWatchDogTimer() +{ + nsresult result; + if (mWatchDogTimer) { + mWatchDogTimer->Cancel(); + } + mWatchDogTimer = do_CreateInstance("@mozilla.org/timer;1", &result); + if (NS_FAILED(result)) { + NS_WARNING("unable to start the timer"); + } else { + // Instead of just doing one timer for a long period do multiple so we + // can check if the user cancelled the printing. + mWatchDogTimer->InitWithCallback(this, WATCH_DOG_INTERVAL, + nsITimer::TYPE_ONE_SHOT); + } + return result; +} + +void +nsPagePrintTimer::StopWatchDogTimer() +{ + if (mWatchDogTimer) { + mWatchDogTimer->Cancel(); + mWatchDogTimer = nullptr; + } +} + //nsRunnable NS_IMETHODIMP nsPagePrintTimer::Run() { bool initNewTimer = true; // Check to see if we are done // inRange will be true if a page is actually printed bool inRange; @@ -56,57 +84,97 @@ nsPagePrintTimer::Run() // donePrinting will be true if it completed successfully or // if the printing was cancelled donePrinting = mPrintEngine->PrintPage(mPrintObj, inRange); if (donePrinting) { // now clean up print or print the next webshell if (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)) { - donePrinting = true; // had a failure.. we are finished.. + mDone = true; // had a failure.. we are finished.. mPrintEngine->SetIsPrinting(false); } } return NS_OK; } // nsITimerCallback NS_IMETHODIMP nsPagePrintTimer::Notify(nsITimer *timer) { + // When finished there may be still pending notifications, which we can just + // ignore. + if (mDone) { + return NS_OK; + } + + // There are three things that call Notify with different values for timer: + // 1) the delay between pages (timer == mTimer) + // 2) canvasPrintState done (timer == null) + // 3) the watch dog timer (timer == mWatchDogTimer) + if (timer && timer == mWatchDogTimer) { + mWatchDogCount++; + if (mWatchDogCount > WATCH_DOG_MAX_COUNT) { + Fail(); + return NS_OK; + } + } else if(!timer) { + // Reset the counter since a mozPrintCallback has finished. + mWatchDogCount = 0; + } + if (mDocViewerPrint) { bool donePrePrint = mPrintEngine->PrePrintPage(); if (donePrePrint) { + 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(); } } return NS_OK; } nsresult nsPagePrintTimer::Start(nsPrintObject* aPO) { mPrintObj = aPO; + mWatchDogCount = 0; + mDone = false; return StartTimer(false); } void nsPagePrintTimer::Stop() { if (mTimer) { mTimer->Cancel(); mTimer = nullptr; } + StopWatchDogTimer(); } + +void +nsPagePrintTimer::Fail() +{ + mDone = true; + Stop(); + if (mPrintEngine) { + mPrintEngine->CleanupOnFailure(NS_OK, false); + } +}
--- a/layout/printing/nsPagePrintTimer.h +++ b/layout/printing/nsPagePrintTimer.h @@ -28,37 +28,48 @@ public: nsPagePrintTimer(nsPrintEngine* aPrintEngine, nsIDocumentViewerPrint* aDocViewerPrint, uint32_t aDelay) : mPrintEngine(aPrintEngine) , mDocViewerPrint(aDocViewerPrint) , mDelay(aDelay) , mFiringCount(0) , mPrintObj(nullptr) + , mWatchDogCount(0) + , mDone(false) { mDocViewerPrint->IncrementDestroyRefCount(); } ~nsPagePrintTimer(); NS_DECL_NSITIMERCALLBACK nsresult Start(nsPrintObject* aPO); NS_IMETHOD Run(); void Stop(); private: nsresult StartTimer(bool aUseDelay); + nsresult StartWatchDogTimer(); + void StopWatchDogTimer(); + void Fail(); nsPrintEngine* mPrintEngine; nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint; nsCOMPtr<nsITimer> mTimer; + nsCOMPtr<nsITimer> mWatchDogTimer; uint32_t mDelay; uint32_t mFiringCount; nsPrintObject * mPrintObj; + uint32_t mWatchDogCount; + bool mDone; + + static const uint32_t WATCH_DOG_INTERVAL = 1000; + static const uint32_t WATCH_DOG_MAX_COUNT = 10; }; nsresult NS_NewPagePrintTimer(nsPagePrintTimer **aResult); #endif /* nsPagePrintTimer_h___ */