From b304902a9daca084bc8b28ab27252f7cef0e2062 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 8 Aug 2016 20:24:09 +0200 Subject: Reduce the critical sections of the PDF mutex Guard only the FPDF_* function calls by the PDF mutex, to make the QPdfDocument kind of reentrant. Change-Id: I76d448dde2604bd258d140fe6bb667cdee9e93c9 Reviewed-by: Simon Hausmann --- src/pdf/qpdfdocument.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp index e1c9b0f..28fbeaf 100644 --- a/src/pdf/qpdfdocument.cpp +++ b/src/pdf/qpdfdocument.cpp @@ -70,6 +70,8 @@ QPdfDocumentPrivate::~QPdfDocumentPrivate() void QPdfDocumentPrivate::clear() { + QMutexLocker lock(pdfMutex()); + if (doc) FPDF_CloseDocument(doc); doc = Q_NULLPTR; @@ -77,6 +79,7 @@ void QPdfDocumentPrivate::clear() if (avail) FPDFAvail_Destroy(avail); avail = Q_NULLPTR; + lock.unlock(); loadComplete = false; @@ -94,7 +97,12 @@ void QPdfDocumentPrivate::updateLastError() lastError = QPdfDocument::NoError; return; } - switch (FPDF_GetLastError()) { + + QMutexLocker lock(pdfMutex()); + const unsigned long error = FPDF_GetLastError(); + lock.unlock(); + + switch (error) { case FPDF_ERR_SUCCESS: lastError = QPdfDocument::NoError; break; case FPDF_ERR_UNKNOWN: lastError = QPdfDocument::UnknownError; break; case FPDF_ERR_FILE: lastError = QPdfDocument::FileNotFoundError; break; @@ -137,8 +145,6 @@ void QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnershi void QPdfDocumentPrivate::_q_tryLoadingWithSizeFromContentHeader() { - const QMutexLocker lock(pdfMutex()); - if (avail) return; @@ -163,13 +169,13 @@ void QPdfDocumentPrivate::initiateAsyncLoadWithTotalSizeKnown(quint64 totalSize) // FPDF_FILEACCESS setup m_FileLen = totalSize; + const QMutexLocker lock(pdfMutex()); + avail = FPDFAvail_Create(this, this); } void QPdfDocumentPrivate::_q_copyFromSequentialSourceDevice() { - const QMutexLocker lock(pdfMutex()); - if (loadComplete) return; @@ -185,7 +191,7 @@ void QPdfDocumentPrivate::_q_copyFromSequentialSourceDevice() void QPdfDocumentPrivate::tryLoadDocument() { - const QMutexLocker lock(pdfMutex()); + QMutexLocker lock(pdfMutex()); if (!FPDFAvail_IsDocAvail(avail, this)) return; @@ -193,7 +199,10 @@ void QPdfDocumentPrivate::tryLoadDocument() Q_ASSERT(!doc); doc = FPDFAvail_GetDocument(avail, password); + lock.unlock(); + updateLastError(); + if (lastError == QPdfDocument::IncorrectPasswordError) emit q->passwordRequired(); else if (doc) @@ -202,8 +211,6 @@ void QPdfDocumentPrivate::tryLoadDocument() void QPdfDocumentPrivate::checkComplete() { - const QMutexLocker lock(pdfMutex()); - if (!avail || loadComplete) return; @@ -214,10 +221,15 @@ void QPdfDocumentPrivate::checkComplete() return; loadComplete = true; + + QMutexLocker lock(pdfMutex()); + for (int i = 0, count = FPDF_GetPageCount(doc); i < count; ++i) if (!FPDFAvail_IsPageAvail(avail, i, this)) loadComplete = false; + lock.unlock(); + if (loadComplete) emit q->documentLoadFinished(); } @@ -259,8 +271,6 @@ QPdfDocument::~QPdfDocument() QPdfDocument::Error QPdfDocument::load(const QString &fileName) { - const QMutexLocker lock(pdfMutex()); - QScopedPointer f(new QFile(fileName)); if (!f->open(QIODevice::ReadOnly)) { d->lastError = FileNotFoundError; @@ -277,8 +287,6 @@ bool QPdfDocument::isLoading() const void QPdfDocument::load(QIODevice *device) { - const QMutexLocker lock(pdfMutex()); - d->load(device, /*transfer ownership*/false); } @@ -289,8 +297,6 @@ void QPdfDocument::setPassword(const QString &password) if (d->password == newPassword) return; - const QMutexLocker lock(pdfMutex()); - d->password = newPassword; emit passwordChanged(); @@ -419,8 +425,6 @@ void QPdfDocument::close() emit aboutToBeClosed(); - const QMutexLocker lock(pdfMutex()); - d->clear(); if (!d->password.isEmpty()) { -- cgit v1.2.3