Bug 1376693 - part2: Make nsPrintEngine::DoCommonPrint() stop initializing the instance when the owner stops using the instance r?dholbert
nsPrintEngine::FinishPrintPreview() may be called when nsAutoScriptBlocker is destroyed in nsPrintEngine::DoCommonPrint(). That means that the owner stopped print preview with the instance. In this case, nsPrintEngine::DoCommonPrint() doesn't need to keep initializing the instance anymore.
MozReview-Commit-ID: DRQfmyW9FEL
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -531,16 +531,24 @@ nsPrintEngine::DoCommonPrint(bool
printData->mPrintObject->mFrameType =
printData->mIsParentAFrameSet ? eFrameSet : eDoc;
// Build the "tree" of PrintObjects
BuildDocTree(printData->mPrintObject->mDocShell, &printData->mPrintDocList,
printData->mPrintObject);
}
+ // The nsAutoScriptBlocker above will now have been destroyed, which may
+ // cause our print/print-preview operation to finish. In this case, we
+ // should immediately return an error code so that the root caller knows
+ // it shouldn't continue to do anything with this instance.
+ if (mIsDestroying || (aIsPrintPreview && !GetIsCreatingPrintPreview())) {
+ return NS_ERROR_FAILURE;
+ }
+
if (!aIsPrintPreview) {
SetIsPrinting(true);
}
// XXX This isn't really correct...
if (!printData->mPrintObject->mDocument ||
!printData->mPrintObject->mDocument->GetRootElement())
return NS_ERROR_GFX_PRINTER_STARTDOC;
@@ -3597,16 +3605,23 @@ nsPrintEngine::FinishPrintPreview()
if (!mPrt) {
/* we're already finished with print preview */
return rv;
}
rv = DocumentReadyForPrinting();
+ // Note that this method may be called while the instance is being
+ // initialized. Some methods which initialize the instance (e.g.,
+ // DoCommonPrint) may need to stop initializing and return error if
+ // this is called. Therefore it's important to set IsCreatingPrintPreview
+ // state to false here. If you need to remove this call of
+ // SetIsCreatingPrintPreview here, you need to keep them being able to
+ // check whether the owner stopped using this instance.
SetIsCreatingPrintPreview(false);
// mPrt may be cleared during a call of nsPrintData::OnEndPrinting()
// because that method invokes some arbitrary listeners.
RefPtr<nsPrintData> printData = mPrt;
if (NS_FAILED(rv)) {
/* cleanup done, let's fire-up an error dialog to notify the user
* what went wrong...