sax/source/fastparser/fastparser.cxx | 45 +++++++++++++++++++++++++++++------ sax/source/fastparser/fastparser.hxx | 6 +++- 2 files changed, 43 insertions(+), 8 deletions(-)
New commits: commit 18f7972ed0ddde0c24b3b756d8e5eb2dc6f6683e Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Oct 11 14:09:52 2013 +0100 fastparser: re-work locking, add high & low watermarks, change sizes etc. Change-Id: I7fe1435addc6dce5a74a8411f7825cea331a5b3f diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 724856b..041b667 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -613,15 +613,23 @@ void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXEx EventList *pEventList = 0; bool done = false; do { - rEntity.maEventsPushed.wait(); - rEntity.maEventsPushed.reset(); - MutexGuard aGuard(rEntity.maEventProtector); + rEntity.maConsumeResume.wait(); + rEntity.maConsumeResume.reset(); + + osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); while (!rEntity.maPendingEvents.empty()) { + if (rEntity.maPendingEvents.empty() <= mnEventLowWater) + maProduceResume.set(); // start producer again + pEventList = rEntity.maPendingEvents.front(); rEntity.maPendingEvents.pop(); + aGuard.clear(); // unlock + if (!consume(pEventList)) done = true; + + aGuard.reset(); // lock } } while (!done); xParser->join(); @@ -794,20 +802,30 @@ OUString lclGetErrorMessage( XML_Error xmlE, const OUString& sSystemId, sal_Int3 void FastSaxParser::deleteUsedEvents() { + osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); + Entity& rEntity = getEntity(); while (!rEntity.maUsedEvents.empty()) { EventList *pEventList = rEntity.maUsedEvents.front(); rEntity.maUsedEvents.pop(); + aGuard.clear(); // unlock + for (size_t i = 0; i < pEventList->size(); ++i) delete (*pEventList)[i]; delete pEventList; + + aGuard.reset(); // lock } } // freeing in producer thread will leak one EventList -#define FREE_IN_MAIN_THREAD 1 -#define SIZE 1000 + +// FIXME: make this a static const size_t in the class ... +#define SIZE 10000 +// FIXME: kill this - it should be in the parse thread I'm convinced :-) +#define FREE_IN_MAIN_THREAD 0 + void FastSaxParser::produce(Event *pEvent) { Entity& rEntity = getEntity(); @@ -821,13 +839,26 @@ void FastSaxParser::produce(Event *pEvent) pEvent->maType == CallbackType::EXCEPTION || rEntity.mpProducedEvents->size() == SIZE) { - MutexGuard aGuard(rEntity.maEventProtector); + osl::ResettableMutexGuard aGuard(rEntity.maEventProtector); + + while (rEntity.maPendingEvents.size() >= mnEventHighWater) + { // pause parsing for a bit + aGuard.clear(); // unlock + rEntity.maProduceResume.wait(); + rEntity.maProduceResume.reset(); + aGuard.reset(); // lock + } + rEntity.maPendingEvents.push(rEntity.mpProducedEvents); rEntity.mpProducedEvents = 0; + + aGuard.clear(); // unlock + + rEntity.maConsumeResume.set(); + #ifndef FREE_IN_MAIN_THREAD deleteUsedEvents(); #endif - rEntity.maEventsPushed.set(); } } diff --git a/sax/source/fastparser/fastparser.hxx b/sax/source/fastparser/fastparser.hxx index 5b387c4..ceba717 100644 --- a/sax/source/fastparser/fastparser.hxx +++ b/sax/source/fastparser/fastparser.hxx @@ -105,7 +105,11 @@ struct Entity : public ParserData std::queue< EventList * > maPendingEvents; std::queue< EventList * > maUsedEvents; osl::Mutex maEventProtector; - osl::Condition maEventsPushed; + + static const size_t mnEventLowWater = 4; + static const size_t mnEventHighWater = 8; + osl::Condition maConsumeResume; + osl::Condition maProduceResume; // copied in copy constructor: _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits