From 03ac42d38e0a0a0bf6eba9f34e51e106ac8131c7 Mon Sep 17 00:00:00 2001 From: thestig Date: Sat, 20 Dec 2014 08:04:00 -0800 Subject: [PATCH] Do not unload pages while loading of the same pages is in progress. BUG=363365,423899 TBR=tsepez@chromium.org Review URL: https://codereview.chromium.org/784403004 Cr-Commit-Position: refs/heads/master@{#309346} --- pdf/pdfium/pdfium_page.cc | 32 ++++++++++++++++++++++++++++++-- pdf/pdfium/pdfium_page.h | 14 ++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc index d8a5dce5a2a2..cd75a1bc3716 100644 --- a/pdf/pdfium/pdfium_page.cc +++ b/pdf/pdfium/pdfium_page.cc @@ -16,6 +16,8 @@ // Used when doing hit detection. #define kTolerance 20.0 +namespace { + // Dictionary Value key names for returning the accessible page content as JSON. const char kPageWidth[] = "width"; const char kPageHeight[] = "height"; @@ -33,6 +35,8 @@ const char kTextNodeTypeText[] = "text"; const char kTextNodeTypeURL[] = "url"; const char kDocLinkURLPrefix[] = "#page"; +} // namespace + namespace chrome_pdf { PDFiumPage::PDFiumPage(PDFiumEngine* engine, @@ -43,15 +47,21 @@ PDFiumPage::PDFiumPage(PDFiumEngine* engine, page_(NULL), text_page_(NULL), index_(i), + loading_count_(0), rect_(r), calculated_links_(false), available_(available) { } PDFiumPage::~PDFiumPage() { + DCHECK_EQ(0, loading_count_); } void PDFiumPage::Unload() { + // Do not unload while in the middle of a load. + if (loading_count_) + return; + if (text_page_) { FPDFText_ClosePage(text_page_); text_page_ = NULL; @@ -71,6 +81,7 @@ FPDF_PAGE PDFiumPage::GetPage() { if (!available_) return NULL; if (!page_) { + ScopedLoadCounter scoped_load(this); page_ = FPDF_LoadPage(engine_->doc(), index_); if (page_ && engine_->form()) { FORM_OnAfterLoadPage(page_, engine_->form()); @@ -83,12 +94,18 @@ FPDF_PAGE PDFiumPage::GetPrintPage() { ScopedUnsupportedFeature scoped_unsupported_feature(engine_); if (!available_) return NULL; - if (!page_) + if (!page_) { + ScopedLoadCounter scoped_load(this); page_ = FPDF_LoadPage(engine_->doc(), index_); + } return page_; } void PDFiumPage::ClosePrintPage() { + // Do not close |page_| while in the middle of a load. + if (loading_count_) + return; + if (page_) { FPDF_ClosePage(page_); page_ = NULL; @@ -98,8 +115,10 @@ void PDFiumPage::ClosePrintPage() { FPDF_TEXTPAGE PDFiumPage::GetTextPage() { if (!available_) return NULL; - if (!text_page_) + if (!text_page_) { + ScopedLoadCounter scoped_load(this); text_page_ = FPDFText_LoadPage(GetPage()); + } return text_page_; } @@ -468,6 +487,15 @@ pp::Rect PDFiumPage::PageToScreen(const pp::Point& offset, new_left, new_top, new_right - new_left + 1, new_bottom - new_top + 1); } +PDFiumPage::ScopedLoadCounter::ScopedLoadCounter(PDFiumPage* page) + : page_(page) { + page_->loading_count_++; +} + +PDFiumPage::ScopedLoadCounter::~ScopedLoadCounter() { + page_->loading_count_--; +} + PDFiumPage::Link::Link() { } diff --git a/pdf/pdfium/pdfium_page.h b/pdf/pdfium/pdfium_page.h index 22ea142988b3..de4317ec9ab0 100644 --- a/pdf/pdfium/pdfium_page.h +++ b/pdf/pdfium/pdfium_page.h @@ -34,9 +34,9 @@ class PDFiumPage { void Unload(); // Gets the FPDF_PAGE for this page, loading and parsing it if necessary. FPDF_PAGE GetPage(); - //Get the FPDF_PAGE for printing. + // Get the FPDF_PAGE for printing. FPDF_PAGE GetPrintPage(); - //Close the printing page. + // Close the printing page. void ClosePrintPage(); // Returns FPDF_TEXTPAGE for the page, loading and parsing it if necessary. @@ -112,6 +112,15 @@ class PDFiumPage { base::Value* CreateTextNode(std::string text); base::Value* CreateURLNode(std::string text, std::string url); + class ScopedLoadCounter { + public: + explicit ScopedLoadCounter(PDFiumPage* page); + ~ScopedLoadCounter(); + + private: + PDFiumPage* const page_; + }; + struct Link { Link(); ~Link(); @@ -125,6 +134,7 @@ class PDFiumPage { FPDF_PAGE page_; FPDF_TEXTPAGE text_page_; int index_; + int loading_count_; pp::Rect rect_; bool calculated_links_; std::vector links_;