diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-12-15 16:17:41 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-12-15 16:17:41 +0100 |
commit | c1ecb9b0e46b5b86a329b6b03a26e13bf8f0c659 (patch) | |
tree | 71aad161fd795877bc661a9b78cfed7a45913991 | |
parent | 233896bae4ecf86583d2ded590581b86c1f75b4d (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.cpp | 34 |
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(); |