From 73e02d24cc66887240e92d24a64100cd6008258e Mon Sep 17 00:00:00 2001 From: cku Date: Sun, 5 Nov 2017 15:34:54 +0800 Subject: [PATCH] Bug 1399787 - Part 13. Handle AbortDocument. r=jwatt While aborting conversion, we need to make sure there is no coversion task executing in the PDFium process before destroying it. MozReview-Commit-ID: 3Iqhe8KmYv2 --HG-- extra : rebase_source : c4597de6c13d35024090ec1e851ad1db5b790c7a extra : source : 753ed705666fd4c55da456fb80604e4552d6bd52 --- gfx/thebes/PrintTargetEMF.cpp | 8 +++++++- gfx/thebes/PrintTargetEMF.h | 1 + widget/windows/PDFiumParent.cpp | 20 +++++++++++++++++++- widget/windows/PDFiumParent.h | 4 ++++ widget/windows/PDFiumProcessParent.cpp | 17 +++++++++++++---- widget/windows/PDFiumProcessParent.h | 2 +- 6 files changed, 45 insertions(+), 7 deletions(-) diff --git a/gfx/thebes/PrintTargetEMF.cpp b/gfx/thebes/PrintTargetEMF.cpp index c9fd6015dc15..a031ada4a6f3 100644 --- a/gfx/thebes/PrintTargetEMF.cpp +++ b/gfx/thebes/PrintTargetEMF.cpp @@ -21,13 +21,14 @@ namespace gfx { PrintTargetEMF::PrintTargetEMF(HDC aDC, const IntSize& aSize) : PrintTarget(/* not using cairo_surface_t */ nullptr, aSize) , mPrinterDC(aDC) + , mWaitingForEMFConversion(false) { } PrintTargetEMF::~PrintTargetEMF() { if (mPDFiumProcess) { - mPDFiumProcess->Delete(); + mPDFiumProcess->Delete(mWaitingForEMFConversion); } } @@ -125,6 +126,7 @@ PrintTargetEMF::EndPage() ::GetDeviceCaps(mPrinterDC, HORZRES), ::GetDeviceCaps(mPrinterDC, VERTRES)); PR_Close(prfile); + mWaitingForEMFConversion = true; return NS_OK; } @@ -160,7 +162,11 @@ PrintTargetEMF::ConvertToEMFDone(const nsresult& aResult, "after the channel was broken."); mWaitingForEMFConversion = false; +<<<<<<< local if (NS_SUCCEEDED(aResult)) { +======= + if (NS_SUCCESSED(aResult)) { +>>>>>>> histedit if (::StartPage(mPrinterDC) > 0) { mozilla::widget::WindowsEMF emf; emf.InitFromFileContents(aEMF.get(), aEMF.Size()); diff --git a/gfx/thebes/PrintTargetEMF.h b/gfx/thebes/PrintTargetEMF.h index d9288d01d5ae..3a6d713e4469 100644 --- a/gfx/thebes/PrintTargetEMF.h +++ b/gfx/thebes/PrintTargetEMF.h @@ -67,6 +67,7 @@ private: RefPtr mRefTarget; PDFiumProcessParent* mPDFiumProcess; HDC mPrinterDC; + bool mWaitingForEMFConversion; }; } // namespace gfx diff --git a/widget/windows/PDFiumParent.cpp b/widget/windows/PDFiumParent.cpp index 2700134173de..f4355a3360dd 100644 --- a/widget/windows/PDFiumParent.cpp +++ b/widget/windows/PDFiumParent.cpp @@ -29,6 +29,11 @@ PDFiumParent::Init(IPC::Channel* aChannel, base::ProcessId aPid) void PDFiumParent::ActorDestroy(ActorDestroyReason aWhy) { + if (mConversionDoneCallback) { + // Since this printing job was aborted, we do not need to report EMF buffer + // back to mTarget. + mConversionDoneCallback(); + } } mozilla::ipc::IPCResult @@ -36,11 +41,24 @@ PDFiumParent::RecvConvertToEMFDone(const nsresult& aResult, mozilla::ipc::Shmem&& aEMFContents) { MOZ_ASSERT(aEMFContents.IsReadable()); - mTarget->ConvertToEMFDone(aResult, Move(aEMFContents)); + + if (mTarget) { + MOZ_ASSERT(!mConversionDoneCallback); + mTarget->ConvertToEMFDone(aResult, Move(aEMFContents)); + } return IPC_OK(); } +void +PDFiumParent::AbortConversion(ConversionDoneCallback aCallback) +{ + // There is no need to report EMF contents back to mTarget since the print + // job was aborted, unset mTarget. + mTarget = nullptr; + mConversionDoneCallback = aCallback; +} + void PDFiumParent::OnChannelConnected(int32_t pid) { diff --git a/widget/windows/PDFiumParent.h b/widget/windows/PDFiumParent.h index 836270913d3f..4ee968e4f95d 100644 --- a/widget/windows/PDFiumParent.h +++ b/widget/windows/PDFiumParent.h @@ -23,11 +23,14 @@ class PDFiumParent final : public PPDFiumParent, NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PDFiumParent) typedef mozilla::gfx::PrintTargetEMF PrintTargetEMF; + typedef std::function ConversionDoneCallback; explicit PDFiumParent(PrintTargetEMF* aTarget); bool Init(IPC::Channel* aChannel, base::ProcessId aPid); + void AbortConversion(ConversionDoneCallback aCallback); + FORWARD_SHMEM_ALLOCATOR_TO(PPDFiumParent) private: ~PDFiumParent() {} @@ -41,6 +44,7 @@ private: void DeallocPPDFiumParent() override; PrintTargetEMF* mTarget; + ConversionDoneCallback mConversionDoneCallback; }; } // namespace widget diff --git a/widget/windows/PDFiumProcessParent.cpp b/widget/windows/PDFiumProcessParent.cpp index 57ff58d34de7..69d2cbcda776 100644 --- a/widget/windows/PDFiumProcessParent.cpp +++ b/widget/windows/PDFiumProcessParent.cpp @@ -49,8 +49,16 @@ PDFiumProcessParent::Launch(PrintTargetEMF* aTarget) } void -PDFiumProcessParent::Delete() +PDFiumProcessParent::Delete(bool aWaitingForEMFConversion) { + if (aWaitingForEMFConversion) { + // Can not kill the PDFium process yet since we are still waiting for a + // EMF conversion response. + mPDFiumParentActor->AbortConversion([this]() { Delete(false); }); + mPDFiumParentActor->Close(); + return; + } + // PDFiumProcessParent::Launch is not called, protocol is not created. // It is safe to destroy this object on any thread. if (!mLaunchThread) { @@ -64,9 +72,10 @@ PDFiumProcessParent::Delete() } mLaunchThread->Dispatch( - NewNonOwningRunnableMethod("PDFiumProcessParent::Delete", - this, - &PDFiumProcessParent::Delete)); + NewNonOwningRunnableMethod("PDFiumProcessParent::Delete", + this, + &PDFiumProcessParent::Delete, + false)); } } // namespace widget diff --git a/widget/windows/PDFiumProcessParent.h b/widget/windows/PDFiumProcessParent.h index d0d772d57c8e..1e1a58dbbd68 100644 --- a/widget/windows/PDFiumProcessParent.h +++ b/widget/windows/PDFiumProcessParent.h @@ -37,7 +37,7 @@ public: bool Launch(PrintTargetEMF* aTarget); - void Delete(); + void Delete(bool aWaitingForEMFConversion); bool CanShutdown() override { return true; }