[Libreoffice-commits] core.git: Branch 'feature/saxparser' - sax/source

Michael Meeks michael.meeks at collabora.com
Fri Oct 11 06:12:22 PDT 2013


 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.meeks at 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:
 


More information about the Libreoffice-commits mailing list