Commit d5c929fc authored by Thomas Freitag's avatar Thomas Freitag Committed by Albert Astals Cid

Add a locker helper and a bool -> enum changes

Bug #59933
parent 1f4a012f
......@@ -60,4 +60,20 @@ typedef pthread_mutex_t GooMutex;
#endif
namespace Poppler {
enum LockMode {
DoNotLock, // for conditional locks: do not lock
DoLock // for conditional locks: do lock
};
class Lock {
public:
Lock(GooMutex *mutexA) : mutex(mutexA) { mode = DoLock; gLockMutex(mutex); }
Lock(GooMutex *mutexA, LockMode modeA) : mutex(mutexA) { mode = modeA; if (mode == DoLock) gLockMutex(mutex); }
~Lock() { if (mode == DoLock) gUnlockMutex(mutex); }
private:
GooMutex *mutex;
LockMode mode;
};
}
#endif
This diff is collapsed.
......@@ -572,7 +572,7 @@ public:
// new_color.
void setColor(AnnotColor *new_color);
void setAppearanceState(const char *state, GBool lock = gTrue);
void setAppearanceState(const char *state, Poppler::LockMode lock = Poppler::DoLock);
// Delete appearance streams and reset appearance state
void invalidateAppearance();
......@@ -627,7 +627,7 @@ protected:
// Updates the field key of the annotation dictionary
// and sets M to the current time
void update(const char *key, Object *value, GBool lock = gTrue);
void update(const char *key, Object *value, Poppler::LockMode lock = Poppler::DoLock);
int refCnt;
......
......@@ -35,11 +35,9 @@
#include "Array.h"
#if MULTITHREADED
# define lockArray gLockMutex(&mutex)
# define unlockArray gUnlockMutex(&mutex)
# define lockArray() Poppler::Lock lock(&mutex)
#else
# define lockArray
# define unlockArray
# define lockArray()
#endif
//------------------------------------------------------------------------
// Array
......@@ -67,32 +65,29 @@ Array::~Array() {
}
Object *Array::copy(XRef *xrefA, Object *obj) {
lockArray;
lockArray();
obj->initArray(xrefA);
for (int i = 0; i < length; ++i) {
Object obj1;
obj->arrayAdd(elems[i].copy(&obj1));
}
unlockArray;
return obj;
}
int Array::incRef() {
lockArray;
lockArray();
++ref;
unlockArray;
return ref;
}
int Array::decRef() {
lockArray;
lockArray();
--ref;
unlockArray;
return ref;
}
void Array::add(Object *elem) {
lockArray;
lockArray();
if (length == size) {
if (length == 0) {
size = 8;
......@@ -103,22 +98,19 @@ void Array::add(Object *elem) {
}
elems[length] = *elem;
++length;
unlockArray;
}
void Array::remove(int i) {
lockArray;
lockArray();
if (i < 0 || i >= length) {
#ifdef DEBUG_MEM
abort();
#else
unlockArray;
return;
#endif
}
--length;
memmove( elems + i, elems + i + 1, sizeof(elems[0]) * (length - i) );
unlockArray;
}
Object *Array::get(int i, Object *obj, int recursion) {
......
......@@ -60,11 +60,9 @@
#endif
#if MULTITHREADED
# define lockFontEngine gLockMutex(&mutex)
# define unlockFontEngine gUnlockMutex(&mutex)
# define lockFontEngine() Poppler::Lock lock(&mutex)
#else
# define lockFontEngine
# define unlockFontEngine
# define lockFontEngine()
#endif
//------------------------------------------------------------------------
......@@ -789,7 +787,7 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xr
CairoFont *font;
GfxFontType fontType;
lockFontEngine;
lockFontEngine();
ref = *gfxFont->getID();
for (i = 0; i < cairoFontCacheSize; ++i) {
......@@ -799,7 +797,6 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xr
fontCache[j] = fontCache[j-1];
}
fontCache[0] = font;
unlockFontEngine;
return font;
}
}
......@@ -818,6 +815,5 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xr
fontCache[j] = fontCache[j-1];
}
fontCache[0] = font;
unlockFontEngine;
return font;
}
......@@ -57,11 +57,11 @@
#include "FileSpec.h"
#if MULTITHREADED
# define lockCatalog gLockMutex(&mutex)
# define unlockCatalog gUnlockMutex(&mutex)
# define lockCatalog() Poppler::Lock lock(&mutex)
# define condLockCatalog(X) Poppler::Lock condlock(&mutex, (X))
#else
# define lockCatalog
# define unlockCatalog
# define lockCatalog()
# define condLockCatalog(X)
#endif
//------------------------------------------------------------------------
// Catalog
......@@ -191,7 +191,7 @@ GooString *Catalog::readMetadata() {
Dict *dict;
Object obj;
lockCatalog;
lockCatalog();
if (metadata.isNone()) {
Object catDict;
......@@ -206,7 +206,6 @@ GooString *Catalog::readMetadata() {
}
if (!metadata.isStream()) {
unlockCatalog;
return NULL;
}
dict = metadata.streamGetDict();
......@@ -218,7 +217,6 @@ GooString *Catalog::readMetadata() {
s = new GooString();
metadata.getStream()->fillGooString(s);
metadata.streamClose();
unlockCatalog;
return s;
}
......@@ -226,31 +224,27 @@ Page *Catalog::getPage(int i)
{
if (i < 1) return NULL;
lockCatalog;
lockCatalog();
if (i > lastCachedPage) {
GBool cached = cachePageTree(i);
if ( cached == gFalse) {
unlockCatalog;
return NULL;
}
}
unlockCatalog;
return pages[i-1];
}
Ref *Catalog::getPageRef(int i, GBool lock)
Ref *Catalog::getPageRef(int i, Poppler::LockMode lock)
{
if (i < 1) return NULL;
if (lock) lockCatalog;
condLockCatalog(lock);
if (i > lastCachedPage) {
GBool cached = cachePageTree(i);
if ( cached == gFalse) {
if (lock) unlockCatalog;
return NULL;
}
}
if (lock) unlockCatalog;
return &pageRefs[i-1];
}
......@@ -300,7 +294,7 @@ GBool Catalog::cachePageTree(int page)
return gFalse;
}
pagesSize = getNumPages(gFalse);
pagesSize = getNumPages(Poppler::DoNotLock);
pages = (Page **)gmallocn(pagesSize, sizeof(Page *));
pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref));
for (int i = 0; i < pagesSize; ++i) {
......@@ -427,7 +421,7 @@ GBool Catalog::cachePageTree(int page)
return gFalse;
}
int Catalog::findPage(int num, int gen, GBool lock) {
int Catalog::findPage(int num, int gen, Poppler::LockMode lock) {
int i;
for (i = 0; i < getNumPages(lock); ++i) {
......@@ -452,12 +446,11 @@ LinkDest *Catalog::findDest(GooString *name) {
obj1.free();
}
if (!found) {
lockCatalog;
lockCatalog();
if (getDestNameTree()->lookup(name, &obj1))
found = gTrue;
else
obj1.free();
unlockCatalog;
}
if (!found)
return NULL;
......@@ -488,7 +481,7 @@ FileSpec *Catalog::embeddedFile(int i)
{
Object efDict;
Object obj;
lockCatalog;
lockCatalog();
obj = getEmbeddedFileNameTree()->getValue(i);
FileSpec *embeddedFile = 0;
if (obj.isRef()) {
......@@ -501,7 +494,6 @@ FileSpec *Catalog::embeddedFile(int i)
Object null;
embeddedFile = new FileSpec(&null);
}
unlockCatalog;
return embeddedFile;
}
......@@ -510,12 +502,11 @@ GooString *Catalog::getJS(int i)
Object obj;
// getJSNameTree()->getValue(i) returns a shallow copy of the object so we
// do not need to free it
lockCatalog;
lockCatalog();
getJSNameTree()->getValue(i).fetch(xref, &obj);
if (!obj.isDict()) {
obj.free();
unlockCatalog;
return 0;
}
Object obj2;
......@@ -527,7 +518,6 @@ GooString *Catalog::getJS(int i)
if (strcmp(obj2.getName(), "JavaScript")) {
obj2.free();
obj.free();
unlockCatalog;
return 0;
}
obj2.free();
......@@ -543,13 +533,12 @@ GooString *Catalog::getJS(int i)
}
obj2.free();
obj.free();
unlockCatalog;
return js;
}
Catalog::PageMode Catalog::getPageMode() {
lockCatalog;
lockCatalog();
if (pageMode == pageModeNull) {
Object catDict, obj;
......@@ -560,7 +549,6 @@ Catalog::PageMode Catalog::getPageMode() {
if (!catDict.isDict()) {
error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
catDict.free();
unlockCatalog;
return pageMode;
}
......@@ -581,13 +569,12 @@ Catalog::PageMode Catalog::getPageMode() {
obj.free();
catDict.free();
}
unlockCatalog;
return pageMode;
}
Catalog::PageLayout Catalog::getPageLayout() {
lockCatalog;
lockCatalog();
if (pageLayout == pageLayoutNull) {
Object catDict, obj;
......@@ -598,7 +585,6 @@ Catalog::PageLayout Catalog::getPageLayout() {
if (!catDict.isDict()) {
error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
catDict.free();
unlockCatalog;
return pageLayout;
}
......@@ -620,7 +606,6 @@ Catalog::PageLayout Catalog::getPageLayout() {
obj.free();
catDict.free();
}
unlockCatalog;
return pageLayout;
}
......@@ -787,13 +772,9 @@ GBool Catalog::indexToLabel(int index, GooString *label)
}
}
int Catalog::getNumPages(GBool lock)
int Catalog::getNumPages(Poppler::LockMode lock)
{
GBool locked = gFalse;
if (lock && numPages == -1) {
locked = gTrue;
lockCatalog;
}
condLockCatalog((numPages == -1 && lock == Poppler::DoLock) ? lock : Poppler::DoNotLock);
if (numPages == -1)
{
Object catDict, pagesDict, obj;
......@@ -802,7 +783,6 @@ int Catalog::getNumPages(GBool lock)
if (!catDict.isDict()) {
error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
catDict.free();
if (locked) unlockCatalog;
return 0;
}
catDict.dictLookup("Pages", &pagesDict);
......@@ -814,7 +794,6 @@ int Catalog::getNumPages(GBool lock)
error(errSyntaxError, -1, "Top-level pages object is wrong type ({0:s})",
pagesDict.getTypeName());
pagesDict.free();
if (locked) unlockCatalog;
return 0;
}
......@@ -832,13 +811,12 @@ int Catalog::getNumPages(GBool lock)
pagesDict.free();
}
if (locked) unlockCatalog;
return numPages;
}
PageLabelInfo *Catalog::getPageLabelInfo()
{
lockCatalog;
lockCatalog();
if (!pageLabelInfo) {
Object catDict;
Object obj;
......@@ -847,24 +825,22 @@ PageLabelInfo *Catalog::getPageLabelInfo()
if (!catDict.isDict()) {
error(errSyntaxError, -1, "Catalog object is wrong type ({0:s})", catDict.getTypeName());
catDict.free();
unlockCatalog;
return NULL;
}
if (catDict.dictLookup("PageLabels", &obj)->isDict()) {
pageLabelInfo = new PageLabelInfo(&obj, getNumPages(gFalse));
pageLabelInfo = new PageLabelInfo(&obj, getNumPages(Poppler::DoLock));
}
obj.free();
catDict.free();
}
unlockCatalog;
return pageLabelInfo;
}
Object *Catalog::getStructTreeRoot()
{
lockCatalog;
lockCatalog();
if (structTreeRoot.isNone())
{
Object catDict;
......@@ -879,13 +855,12 @@ Object *Catalog::getStructTreeRoot()
catDict.free();
}
unlockCatalog;
return &structTreeRoot;
}
Object *Catalog::getOutline()
{
lockCatalog;
lockCatalog();
if (outline.isNone())
{
Object catDict;
......@@ -900,13 +875,12 @@ Object *Catalog::getOutline()
catDict.free();
}
unlockCatalog;
return &outline;
}
Object *Catalog::getDests()
{
lockCatalog;
lockCatalog();
if (dests.isNone())
{
Object catDict;
......@@ -921,7 +895,6 @@ Object *Catalog::getDests()
catDict.free();
}
unlockCatalog;
return &dests;
}
......@@ -943,9 +916,9 @@ Catalog::FormType Catalog::getFormType()
return res;
}
Form *Catalog::getForm(GBool lock)
Form *Catalog::getForm(Poppler::LockMode lock)
{
if (lock) lockCatalog;
condLockCatalog(lock);
if (!form) {
if (acroForm.isDict()) {
form = new Form(doc, &acroForm);
......@@ -954,20 +927,18 @@ Form *Catalog::getForm(GBool lock)
}
}
if (lock) unlockCatalog;
return form;
}
ViewerPreferences *Catalog::getViewerPreferences()
{
lockCatalog;
lockCatalog();
if (!viewerPrefs) {
if (viewerPreferences.isDict()) {
viewerPrefs = new ViewerPreferences(viewerPreferences.getDict());
}
}
unlockCatalog;
return viewerPrefs;
}
......
......@@ -107,13 +107,13 @@ public:
GBool isOk() { return ok; }
// Get number of pages.
int getNumPages(GBool lock = gTrue);
int getNumPages(Poppler::LockMode lock = Poppler::DoLock);
// Get a page.
Page *getPage(int i);
// Get the reference for a page object.
Ref *getPageRef(int i, GBool lock = gTrue);
Ref *getPageRef(int i, Poppler::LockMode lock = Poppler::DoLock);
// Return base URI, or NULL if none.
GooString *getBaseURI() { return baseURI; }
......@@ -127,7 +127,7 @@ public:
// Find a page, given its object ID. Returns page number, or 0 if
// not found.
int findPage(int num, int gen, GBool lock = gTrue);
int findPage(int num, int gen, Poppler::LockMode lock = Poppler::DoLock);
// Find a named destination. Returns the link destination, or
// NULL if <name> is not a destination.
......@@ -165,7 +165,7 @@ public:
};
FormType getFormType();
Form* getForm(GBool lock = gTrue);
Form* getForm(Poppler::LockMode lock = Poppler::DoLock);
ViewerPreferences *getViewerPreferences();
......@@ -228,7 +228,6 @@ private:
PageMode pageMode; // page mode
PageLayout pageLayout; // page layout
void createPages(); // create pages for caching
GBool cachePageTree(int page); // Cache first <page> pages.
Object *findDestInTree(Object *tree, GooString *name, Object *obj);
......
......@@ -41,11 +41,9 @@
#include "Dict.h"
#if MULTITHREADED
# define lockDict gLockMutex(&mutex)
# define unlockDict gUnlockMutex(&mutex)
# define lockDict() Poppler::Lock lock(&mutex)
#else
# define lockDict
# define unlockDict
# define lockDict()
#endif
//------------------------------------------------------------------------
// Dict
......@@ -104,7 +102,7 @@ Dict::Dict(Dict* dictA) {
}
Dict *Dict::copy(XRef *xrefA) {
lockDict;
lockDict();
Dict *dictA = new Dict(this);
dictA->xref = xrefA;
for (int i=0; i<length; i++) {
......@@ -117,7 +115,6 @@ Dict *Dict::copy(XRef *xrefA) {
obj.free();
}
}
unlockDict;
return dictA;
}
......@@ -135,21 +132,19 @@ Dict::~Dict() {
}
int Dict::incRef() {
lockDict;
lockDict();
++ref;
unlockDict;
return ref;
}
int Dict::decRef() {
lockDict;
lockDict();
--ref;
unlockDict;
return ref;
}
void Dict::add(char *key, Object *val) {
lockDict;
lockDict();
if (sorted) {
// We use add on very few occasions so
// virtually this will never be hit
......@@ -167,16 +162,14 @@ void Dict::add(char *key, Object *val) {
entries[length].key = key;
entries[length].val = *val;
++length;
unlockDict;
}
inline DictEntry *Dict::find(const char *key) {
if (!sorted && length >= SORT_LENGTH_LOWER_LIMIT)
{
lockDict;
lockDict();
sorted = gTrue;
std::sort(entries, entries+length, cmpDictEntries);
unlockDict;
}
if (sorted) {
......@@ -200,7 +193,7 @@ GBool Dict::hasKey(const char *key) {
}
void Dict::remove(const char *key) {
lockDict;
lockDict();
if (sorted) {
const int pos = binarySearch(key, entries, length);
if (pos != -1) {
......@@ -214,7 +207,6 @@ void Dict::remove(const char *key) {
bool found = false;
DictEntry tmp;
if(length == 0) {
unlockDict;
return;
}
......@@ -225,7 +217,6 @@ void Dict::remove(const char *key) {
}
}
if(!found) {
unlockDict;
return;
}
//replace the deleted entry with the last entry
......@@ -234,7 +225,6 @@ void Dict::remove(const char *key) {
if (i!=length) //don't copy the last entry if it is deleted
entries[i] = tmp;
}
unlockDict;
}
void Dict::set(const char *key, Object *val) {
......@@ -245,10 +235,9 @@ void Dict::set(const char *key, Object *val) {
}
e = find (key);
if (e) {
lockDict;
lockDict();
e->val.free();
e->val = *val;
unlockDict;
} else {
add (copyString(key), val);
}
......
......@@ -73,7 +73,7 @@ GooList *FontInfoScanner::scan(int nPages) {
page = doc->getPage(pg);
if (!page) continue;
if ((resDict = page->getResourceDict(xrefA))) {
if ((resDict = page->getResourceDictCopy(xrefA))) {
scanFonts(xrefA, resDict, result);
delete resDict;
}
......
......@@ -77,11 +77,9 @@
#include "Hints.h"
#if MULTITHREADED
# define lockPDFDoc gLockMutex(&mutex)
# define unlockPDFDoc gUnlockMutex(&mutex)
# define lockPDFDoc() Poppler::Lock lock(&mutex)
#else
# define lockPDFDoc
# define unlockPDFDoc
# define lockPDFDoc()
#endif
//------------------------------------------------------------------------
......@@ -258,12 +256,11 @@ PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword,
}
GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
lockPDFDoc;
lockPDFDoc();
str->setPos(0, -1);
if (str->getPos() < 0)
{
error(errSyntaxError, -1, "Document base stream is not seekable");
unlockPDFDoc;
return gFalse;
}
......@@ -283,14 +280,12 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
if (!xref->isOk()) {
error(errSyntaxError, -1, "Couldn't read xref table");
errCode = xref->getErrorCode();
unlockPDFDoc;
return gFalse;
}
// check for encryption
if (!checkEncryption(ownerPassword, userPassword)) {
errCode = errEncrypted;
unlockPDFDoc;
return gFalse;
}
......@@ -309,13 +304,11 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) {
if (catalog && !catalog->isOk()) {
error(errSyntaxError, -1, "Couldn't read page catalog");
errCode = errBadCatalog;
unlockPDFDoc;
return gFalse;
}
}
// done
unlockPDFDoc;
return gTrue;
}
......@@ -1595,10 +1588,9 @@ Guint PDFDoc::writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, G
Outline *PDFDoc::getOutline()
{
if (!outline) {
lockPDFDoc;
lockPDFDoc();
// read outline
outline = new Outline(catalog->getOutline(), xref);
unlockPDFDoc;
}
return outline;
......@@ -1755,18 +1747,15 @@ Page *PDFDoc::getPage(int page)
if ((page < 1) || page > getNumPages()) return NULL;
if (isLinearized()) {
lockPDFDoc;
lockPDFDoc();
if (!pageCache) {
pageCache = (Page **) gmallocn(getNumPages(), sizeof(Page *));
for (int i = 0; i < getNumPages(); i++) {
pageCache[i] = NULL;
}
}
unlockPDFDoc;
if (!pageCache[page-1]) {
lockPDFDoc;
pageCache[page-1] = parsePage(page);
unlockPDFDoc;
}
if (pageCache[page-1]) {
return pageCache[page-1];
......
......@@ -59,11 +59,9 @@
#include "Form.h"
#if MULTITHREADED
# define lockPage gLockMutex(&mutex)
# define unlockPage gUnlockMutex(&mutex)
# define lockPage() Poppler::Lock lock(&mutex)
#else
# define lockPage
# define unlockPage
# define lockPage()
#endif
//------------------------------------------------------------------------
// PDFRectangle
......@@ -359,11 +357,13 @@ Page::~Page() {
#endif
}
Dict *Page::getResourceDict(XRef *xrefA) {
lockPage;
Dict *dict = (xrefA == NULL) ? attrs->getResourceDict() : attrs->getResourceDict()->copy(xrefA);
unlockPage;
return dict;
Dict *Page::getResourceDict() {
return attrs->getResourceDict();
}
Dict *Page::getResourceDictCopy(XRef *xrefA) {
lockPage();