diff --git a/goo/GooMutex.h b/goo/GooMutex.h index 3f53a62..fbef476 100644 --- a/goo/GooMutex.h +++ b/goo/GooMutex.h @@ -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 diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 48af4eb..d5c62b7 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -68,11 +68,11 @@ #include #if MULTITHREADED -# define lockAnnot gLockMutex(&mutex) -# define unlockAnnot gUnlockMutex(&mutex) +# define lockAnnot() Poppler::Lock lock(&mutex) +# define condLockAnnot(X) Poppler::Lock condlock(&mutex, (X)) #else -# define lockAnnot -# define unlockAnnot +# define lockAnnot() +# define condLockAnnot(X) #endif #define fieldFlagReadOnly 0x00000001 @@ -1213,7 +1213,7 @@ void Annot::initialize(PDFDoc *docA, Dict *dict) { if (dict->lookupNF("P", &obj1)->isRef()) { Ref ref = obj1.getRef(); - page = doc->getCatalog()->findPage (ref.num, ref.gen, gFalse); + page = doc->getCatalog()->findPage (ref.num, ref.gen, Poppler::DoNotLock); } else { page = 0; } @@ -1350,8 +1350,8 @@ GBool Annot::inRect(double x, double y) const { return rect->contains(x, y); } -void Annot::update(const char *key, Object *value, GBool lock) { - if (lock) lockAnnot; +void Annot::update(const char *key, Object *value, Poppler::LockMode lock) { + condLockAnnot(lock); /* Set M to current time, unless we are updating M itself */ if (strcmp(key, "M") != 0) { delete modified; @@ -1365,11 +1365,10 @@ void Annot::update(const char *key, Object *value, GBool lock) { annotObj.dictSet(const_cast(key), value); xref->setModifiedObject(&annotObj, ref); - if (lock) unlockAnnot; } void Annot::setContents(GooString *new_content) { - lockAnnot; + lockAnnot(); delete contents; if (new_content) { @@ -1385,12 +1384,11 @@ void Annot::setContents(GooString *new_content) { Object obj1; obj1.initString(contents->copy()); - update ("Contents", &obj1, gFalse); - unlockAnnot; + update ("Contents", &obj1, Poppler::DoNotLock); } void Annot::setName(GooString *new_name) { - lockAnnot; + lockAnnot(); delete name; if (new_name) { @@ -1401,12 +1399,11 @@ void Annot::setName(GooString *new_name) { Object obj1; obj1.initString(name->copy()); - update ("NM", &obj1, gFalse); - unlockAnnot; + update ("NM", &obj1, Poppler::DoNotLock); } void Annot::setModified(GooString *new_modified) { - lockAnnot; + lockAnnot(); delete modified; if (new_modified) @@ -1416,51 +1413,47 @@ void Annot::setModified(GooString *new_modified) { Object obj1; obj1.initString(modified->copy()); - update ("M", &obj1, gFalse); - unlockAnnot; + update ("M", &obj1, Poppler::DoNotLock); } void Annot::setFlags(Guint new_flags) { - lockAnnot; + lockAnnot(); Object obj1; flags = new_flags; obj1.initInt(flags); - update ("F", &obj1, gFalse); - unlockAnnot; + update ("F", &obj1, Poppler::DoNotLock); } void Annot::setBorder(AnnotBorderArray *new_border) { - lockAnnot; + lockAnnot(); delete border; if (new_border) { Object obj1; new_border->writeToObject(xref, &obj1); - update ("Border", &obj1, gFalse); + update ("Border", &obj1, Poppler::DoNotLock); border = new_border; } else { border = NULL; } - unlockAnnot; } void Annot::setColor(AnnotColor *new_color) { - lockAnnot; + lockAnnot(); delete color; if (new_color) { Object obj1; new_color->writeToObject(xref, &obj1); - update ("C", &obj1, gFalse); + update ("C", &obj1, Poppler::DoNotLock); color = new_color; } else { color = NULL; } - unlockAnnot; } void Annot::setPage(int pageIndex, GBool updateP) { - lockAnnot; + lockAnnot(); Page *pageobj = doc->getPage(pageIndex); Object obj1; @@ -1474,16 +1467,15 @@ void Annot::setPage(int pageIndex, GBool updateP) { } if (updateP) { - update("P", &obj1, gFalse); + update("P", &obj1, Poppler::DoNotLock); } - unlockAnnot; } -void Annot::setAppearanceState(const char *state, GBool lock) { +void Annot::setAppearanceState(const char *state, Poppler::LockMode lock) { + condLockAnnot(lock); if (!state) return; - if (lock) lockAnnot; delete appearState; appearState = new GooString(state); @@ -1492,7 +1484,7 @@ void Annot::setAppearanceState(const char *state, GBool lock) { Object obj1; obj1.initName(state); - update ("AS", &obj1, gFalse); + update ("AS", &obj1, Poppler::DoNotLock); // The appearance state determines the current appearance stream appearance.free(); @@ -1501,24 +1493,22 @@ void Annot::setAppearanceState(const char *state, GBool lock) { } else { appearance.initNull(); } - if (lock) unlockAnnot; } void Annot::invalidateAppearance() { - lockAnnot; + lockAnnot(); if (appearStreams) { // Remove existing appearance streams appearStreams->removeAllStreams(); } delete appearStreams; appearStreams = NULL; - setAppearanceState("Off", gFalse); // Default appearance state + setAppearanceState("Off", Poppler::DoNotLock); // Default appearance state Object obj1; obj1.initNull(); - update ("AP", &obj1, gFalse); // Remove AP - update ("AS", &obj1, gFalse); // Remove AS - unlockAnnot; + update ("AP", &obj1, Poppler::DoNotLock); // Remove AP + update ("AS", &obj1, Poppler::DoNotLock); // Remove AS } double Annot::getXMin() { @@ -1548,19 +1538,16 @@ void Annot::removeReferencedObjects() { } void Annot::incRefCnt() { - lockAnnot; + lockAnnot(); refCnt++; - unlockAnnot; } void Annot::decRefCnt() { - lockAnnot; + lockAnnot(); if (--refCnt == 0) { - unlockAnnot; delete this; return; } - unlockAnnot; } Annot::~Annot() { @@ -1787,7 +1774,7 @@ GBool Annot::isVisible(GBool printing) { void Annot::draw(Gfx *gfx, GBool printing) { Object obj; - lockAnnot; + lockAnnot(); if (!isVisible (printing)) return; @@ -1796,7 +1783,6 @@ void Annot::draw(Gfx *gfx, GBool printing) { gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -2406,7 +2392,7 @@ void AnnotText::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { ca = opacity; @@ -2468,7 +2454,6 @@ void AnnotText::draw(Gfx *gfx, GBool printing) { rect->x1, rect->y1, rect->x2, rect->y2); } obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -2557,13 +2542,12 @@ void AnnotLink::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); // draw the appearance stream appearance.fetch(gfx->getXRef(), &obj); gfx->drawAnnot(&obj, border, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -2988,7 +2972,7 @@ void AnnotFreeText::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { generateFreeTextAppearance(); } @@ -2998,7 +2982,6 @@ void AnnotFreeText::draw(Gfx *gfx, GBool printing) { gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } // Before retrieving the res dict, regenerate the appearance stream if needed, @@ -3462,7 +3445,7 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { generateLineAppearance(); } @@ -3478,7 +3461,6 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) { rect->x1, rect->y1, rect->x2, rect->y2); } obj.free(); - unlockAnnot; } // Before retrieving the res dict, regenerate the appearance stream if needed, @@ -3629,7 +3611,7 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull() || type == typeHighlight) { GBool blendMultiply = gTrue; ca = opacity; @@ -3788,7 +3770,6 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) { rect->x1, rect->y1, rect->x2, rect->y2); } obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -3825,7 +3806,7 @@ AnnotWidget::~AnnotWidget() { void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) { Object obj1; - form = doc->getCatalog()->getForm(gFalse); + form = doc->getCatalog()->getForm(Poppler::DoNotLock); if(dict->lookup("H", &obj1)->isName()) { const char *modeName = obj1.getName(); @@ -5011,7 +4992,7 @@ void AnnotWidget::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); addDingbatsResource = gFalse; // Only construct the appearance stream when @@ -5055,7 +5036,6 @@ void AnnotWidget::draw(Gfx *gfx, GBool printing) { gfx->popResources(); } obj.free(); - unlockAnnot; } @@ -5125,7 +5105,7 @@ void AnnotMovie::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull() && movie->getShowPoster()) { int width, height; Object poster; @@ -5209,7 +5189,6 @@ void AnnotMovie::draw(Gfx *gfx, GBool printing) { gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -5435,7 +5414,7 @@ void AnnotGeometry::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { ca = opacity; @@ -5553,7 +5532,6 @@ void AnnotGeometry::draw(Gfx *gfx, GBool printing) { gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -5758,7 +5736,7 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { appearBBox = new AnnotAppearanceBBox(rect); ca = opacity; @@ -5845,7 +5823,6 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) { rect->x1, rect->y1, rect->x2, rect->y2); } obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -5997,7 +5974,7 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { appearBBox = new AnnotAppearanceBBox(rect); ca = opacity; @@ -6059,7 +6036,6 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) { rect->x1, rect->y1, rect->x2, rect->y2); } obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -6231,7 +6207,7 @@ void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { ca = opacity; @@ -6276,7 +6252,6 @@ void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) { gfx->drawAnnot(&obj, border, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ @@ -6399,7 +6374,7 @@ void AnnotSound::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; - lockAnnot; + lockAnnot(); if (appearance.isNull()) { ca = opacity; @@ -6439,7 +6414,6 @@ void AnnotSound::draw(Gfx *gfx, GBool printing) { gfx->drawAnnot(&obj, border, color, rect->x1, rect->y1, rect->x2, rect->y2); obj.free(); - unlockAnnot; } //------------------------------------------------------------------------ diff --git a/poppler/Annot.h b/poppler/Annot.h index 65b8eac..806d813 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -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; diff --git a/poppler/Array.cc b/poppler/Array.cc index d23ed5d..142dafc 100644 --- a/poppler/Array.cc +++ b/poppler/Array.cc @@ -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) { diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc index beb4e37..6f99ace 100644 --- a/poppler/CairoFontEngine.cc +++ b/poppler/CairoFontEngine.cc @@ -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; } diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index b7f7ede..d9fa229 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -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; } diff --git a/poppler/Catalog.h b/poppler/Catalog.h index ac7505f..0ddc30a 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -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 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 pages. Object *findDestInTree(Object *tree, GooString *name, Object *obj); diff --git a/poppler/Dict.cc b/poppler/Dict.cc index 95ed585..a349650 100644 --- a/poppler/Dict.cc +++ b/poppler/Dict.cc @@ -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= 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); } diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc index d33226e..8fc89e9 100644 --- a/poppler/FontInfo.cc +++ b/poppler/FontInfo.cc @@ -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; } diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index c184348..5a8c3d3 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -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]; diff --git a/poppler/Page.cc b/poppler/Page.cc index 96040d8..5ce0b23 100644 --- a/poppler/Page.cc +++ b/poppler/Page.cc @@ -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(); + return attrs->getResourceDict()->copy(xrefA); } void Page::replaceXRef(XRef *xrefA) { @@ -411,7 +411,7 @@ void Page::addAnnot(Annot *annot) { // Make sure we have annots before adding the new one // even if it's an empty list so that we can safely // call annots->appendAnnot(annot) - lockPage; + lockPage(); getAnnots(); if (annotsObj.isNull()) { @@ -441,14 +441,13 @@ void Page::addAnnot(Annot *annot) { annots->appendAnnot(annot); annot->setPage(num, gTrue); - unlockPage; } void Page::removeAnnot(Annot *annot) { Ref annotRef = annot->getRef(); Object annArray; - lockPage; + lockPage(); getAnnots(&annArray); if (annArray.isArray()) { int idx = -1; @@ -465,7 +464,6 @@ void Page::removeAnnot(Annot *annot) { if (idx == -1) { error(errInternal, -1, "Annotation doesn't belong to this page"); annArray.free(); - unlockPage; return; } annots->removeAnnot(annot); // Gracefully fails on popup windows @@ -481,7 +479,6 @@ void Page::removeAnnot(Annot *annot) { annArray.free(); annot->removeReferencedObjects(); // Note: Might recurse in removeAnnot again annot->setPage(0, gFalse); - unlockPage; } Links *Page::getLinks() { @@ -566,7 +563,7 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, annotDisplayDecideCbk, annotDisplayDecideCbkData)) { return; } - lockPage; + lockPage(); XRef *localXRef = (copyXRef) ? xref->copy() : xref; if (copyXRef) { replaceXRef(localXRef); @@ -612,7 +609,6 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI, replaceXRef(doc->getXRef()); delete localXRef; } - unlockPage; } void Page::display(Gfx *gfx) { @@ -641,11 +637,10 @@ GBool Page::loadThumb(unsigned char **data_out, GfxImageColorMap *colorMap; /* Get stream dict */ - lockPage; + lockPage(); thumb.fetch(xref, &fetched_thumb); if (!fetched_thumb.isStream()) { fetched_thumb.free(); - unlockPage; return gFalse; } @@ -728,7 +723,6 @@ GBool Page::loadThumb(unsigned char **data_out, delete colorMap; fail1: - unlockPage; fetched_thumb.free(); return success; diff --git a/poppler/Page.h b/poppler/Page.h index 464b030..1c9d0a9 100644 --- a/poppler/Page.h +++ b/poppler/Page.h @@ -174,7 +174,8 @@ public: Ref getRef() { return pageRef; } // Get resource dictionary. - Dict *getResourceDict(XRef *xrefA = NULL); + Dict *getResourceDict(); + Dict *getResourceDictCopy(XRef *xrefA); // Get annotations array. Object *getAnnots(Object *obj, XRef *xrefA = NULL) { return annotsObj.fetch((xrefA == NULL) ? xref : xrefA, obj); } diff --git a/poppler/Stream.cc b/poppler/Stream.cc index 3e541c6..9f95b81 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -88,11 +88,9 @@ static GBool setDJSYSFLAGS = gFalse; #endif #if MULTITHREADED -# define lockStream gLockMutex(&mutex) -# define unlockStream gUnlockMutex(&mutex) +# define lockStream() Poppler::Lock lock(&mutex) #else -# define lockStream -# define unlockStream +# define lockStream() #endif //------------------------------------------------------------------------ // Stream (base class) @@ -112,16 +110,14 @@ Stream::~Stream() { } int Stream::incRef() { - lockStream; + lockStream(); ++ref; - unlockStream; return ref; } int Stream::decRef() { - lockStream; + lockStream(); --ref; - unlockStream; return ref; } diff --git a/poppler/XRef.cc b/poppler/XRef.cc index c0d37d0..d235273 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -70,11 +70,11 @@ #define defPermFlags 0xfffc #if MULTITHREADED -# define lockXRef gLockMutex(&mutex) -# define unlockXRef gUnlockMutex(&mutex) +# define lockXRef() Poppler::Lock lock(&mutex) +# define condLockXRef(X) Poppler::Lock condlock(&mutex, (X)) #else -# define lockXRef -# define unlockXRef +# define lockXRef() +# define condLockXRef(X) #endif //------------------------------------------------------------------------ @@ -1134,7 +1134,7 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) { Parser *parser; Object obj1, obj2, obj3; - if (recursion == 0) lockXRef; + condLockXRef((recursion == 0) ? Poppler::DoLock : Poppler::DoNotLock); // check for bogus ref - this can happen in corrupted PDF files if (num < 0 || num >= size) { goto err; @@ -1143,7 +1143,6 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) { e = getEntry(num); if(!e->obj.isNull ()) { //check for updated object obj = e->obj.copy(obj); - if (recursion == 0) unlockXRef; return obj; } @@ -1245,20 +1244,18 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) { goto err; } - if (recursion == 0) unlockXRef; return obj; err: - if (recursion == 0) unlockXRef; return obj->initNull(); } void XRef::lock() { - lockXRef; + gLockMutex(&mutex); } void XRef::unlock() { - unlockXRef; + gUnlockMutex(&mutex); } Object *XRef::getDocInfo(Object *obj) { @@ -1315,7 +1312,7 @@ int XRef::getNumEntry(Goffset offset) } void XRef::add(int num, int gen, Goffset offs, GBool used) { - lockXRef; + lockXRef(); if (num >= size) { if (num >= capacity) { entries = (XRefEntry *)greallocn(entries, num + 1, sizeof(XRefEntry)); @@ -1341,21 +1338,18 @@ void XRef::add(int num, int gen, Goffset offs, GBool used) { e->type = xrefEntryFree; e->offset = 0; } - unlockXRef; } void XRef::setModifiedObject (Object* o, Ref r) { - lockXRef; + lockXRef(); if (r.num < 0 || r.num >= size) { error(errInternal, -1,"XRef::setModifiedObject on unknown ref: {0:d}, {1:d}\n", r.num, r.gen); - unlockXRef; return; } XRefEntry *e = getEntry(r.num); e->obj.free(); o->copy(&(e->obj)); e->setFlag(XRefEntry::Updated, gTrue); - unlockXRef; } Ref XRef::addIndirectObject (Object* o) { @@ -1389,22 +1383,19 @@ Ref XRef::addIndirectObject (Object* o) { } void XRef::removeIndirectObject(Ref r) { - lockXRef; + lockXRef(); if (r.num < 0 || r.num >= size) { error(errInternal, -1,"XRef::removeIndirectObject on unknown ref: {0:d}, {1:d}\n", r.num, r.gen); - unlockXRef; return; } XRefEntry *e = getEntry(r.num); if (e->type == xrefEntryFree) { - unlockXRef; return; } e->obj.free(); e->type = xrefEntryFree; e->gen++; e->setFlag(XRefEntry::Updated, gTrue); - unlockXRef; } void XRef::writeXRef(XRef::XRefWriter *writer, GBool writeAllEntries) {