summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-15 16:17:41 +0100
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-15 16:17:41 +0100
commitc1ecb9b0e46b5b86a329b6b03a26e13bf8f0c659 (patch)
tree71aad161fd795877bc661a9b78cfed7a45913991
parent233896bae4ecf86583d2ded590581b86c1f75b4d (diff)
Sprinkle global locks around the API calls
The library is not thread-safe at all with plenty of global variables. The common use-case seems to be one PDF document per process, which perfectly matches Chromium's architecture.
-rw-r--r--src/pdf/qpdfdocument.cpp34
1 files changed, 15 insertions, 19 deletions
diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp
index 394182e..d6aed74 100644
--- a/src/pdf/qpdfdocument.cpp
+++ b/src/pdf/qpdfdocument.cpp
@@ -6,23 +6,17 @@
#include <QIODevice>
#include <QMutex>
+// The library is not thread-safe at all, it has a lot of global variables.
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, pdfMutex, (QMutex::Recursive));
static int libraryRefCount;
-static QMutex libraryInitializerMutex;
-
-// PDFium stores the error code when loading a document in a global
-// variable, but that is only set from the FPDF_Load*Document functions.
-// Therefore this mutex serializes access to the loading.
-static QMutex documentLoadMutex;
QPdfDocumentPrivate::QPdfDocumentPrivate()
: doc(0)
{
- {
- QMutexLocker lock(&libraryInitializerMutex);
- if (libraryRefCount == 0)
- FPDF_InitLibrary();
- ++libraryRefCount;
- }
+ QMutexLocker lock(pdfMutex());
+ if (libraryRefCount == 0)
+ FPDF_InitLibrary();
+ ++libraryRefCount;
// FPDF_FILEACCESS setup
m_Param = this;
@@ -31,19 +25,19 @@ QPdfDocumentPrivate::QPdfDocumentPrivate()
QPdfDocumentPrivate::~QPdfDocumentPrivate()
{
+ QMutexLocker lock(pdfMutex());
if (doc)
FPDF_CloseDocument(doc);
doc = 0;
- {
- QMutexLocker lock(&libraryInitializerMutex);
- if (!--libraryRefCount)
- FPDF_DestroyLibrary();
- }
+ if (!--libraryRefCount)
+ FPDF_DestroyLibrary();
}
QPdfDocument::Error QPdfDocumentPrivate::load(QIODevice *newDevice, bool transferDeviceOwnership, const QString &documentPassword)
{
+ QMutexLocker lock(pdfMutex());
+
if (doc)
FPDF_CloseDocument(doc);
@@ -61,8 +55,6 @@ QPdfDocument::Error QPdfDocumentPrivate::load(QIODevice *newDevice, bool transfe
password = documentPassword.toUtf8();
- QMutexLocker loadLocker(&documentLoadMutex);
-
doc = FPDF_LoadCustomDocument(this, password.constData());
switch (FPDF_GetLastError()) {
case FPDF_ERR_SUCCESS: return QPdfDocument::NoError;
@@ -109,6 +101,7 @@ int QPdfDocument::pageCount() const
{
if (!d->doc)
return 0;
+ QMutexLocker lock(pdfMutex());
return FPDF_GetPageCount(d->doc);
}
@@ -117,6 +110,7 @@ QSizeF QPdfDocument::pageSize(int page) const
QSizeF result;
if (!d->doc)
return result;
+ QMutexLocker lock(pdfMutex());
FPDF_GetPageSizeByIndex(d->doc, page, &result.rwidth(), &result.rheight());
return result;
}
@@ -126,6 +120,8 @@ QImage QPdfDocument::render(int page, const QSizeF &pageSize)
if (!d->doc)
return QImage();
+ QMutexLocker lock(pdfMutex());
+
FPDF_PAGE pdfPage = FPDF_LoadPage(d->doc, page);
if (!pdfPage)
return QImage();