[Libreoffice-commits] core.git: 4 commits - include/oox oox/source sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Mon Nov 25 07:56:19 PST 2013


 include/oox/core/xmlfilterbase.hxx        |    8 -
 oox/source/core/xmlfilterbase.cxx         |  173 ++++++++++++-------------
 sc/source/filter/inc/workbookhelper.hxx   |    6 
 sc/source/filter/oox/workbookfragment.cxx |  202 ++++++++++++++++++++++++++++--
 sc/source/filter/oox/workbookhelper.cxx   |    7 -
 5 files changed, 297 insertions(+), 99 deletions(-)

New commits:
commit e00562d9835bd82d74ef0301ea7425ff769915df
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 20:57:40 2013 -0500

    Allow worker threads to use their own FastParser instances.
    
    To prevent deadlock during threaded sheet stream parsing.  It now
    deadlocks at a different place.
    
    Change-Id: I0ba0f2c9a257e71b0a340ab14e369b06d5fd8829

diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx
index 87234fb..76eb091 100644
--- a/include/oox/core/xmlfilterbase.hxx
+++ b/include/oox/core/xmlfilterbase.hxx
@@ -56,8 +56,7 @@ namespace oox {
 namespace core {
 
 class FragmentHandler;
-
-// ============================================================================
+class FastParser;
 
 struct TextField {
     com::sun::star::uno::Reference< com::sun::star::text::XText > xText;
@@ -107,7 +106,8 @@ public:
 
         @return  True, if the fragment could be imported.
      */
-    bool                importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler );
+    bool importFragment( const rtl::Reference<FragmentHandler>& rxHandler );
+    bool importFragment( const rtl::Reference<FragmentHandler>& rxHandler, FastParser& rParser );
 
     /** Imports a fragment into an xml::dom::XDocument.
 
@@ -231,6 +231,8 @@ public:
 
     void importDocumentProperties();
 
+    FastParser* createParser() const;
+
 protected:
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
         implGetInputStream( utl::MediaDescriptor& rMediaDesc ) const;
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index dddc29c..30f3848 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -143,6 +143,13 @@ struct NamespaceIds: public rtl::StaticWithInit<
     }
 };
 
+void registerNamespaces( FastParser& rParser )
+{
+    const Sequence< beans::Pair<OUString, sal_Int32> > ids = NamespaceIds::get();
+    for (sal_Int32 i = 0; i < ids.getLength(); ++i)
+        rParser.registerNamespace(ids[i].Second);
+}
+
 } // namespace
 
 struct XmlFilterBaseImpl
@@ -164,10 +171,7 @@ XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxCo
     maVmlSuffix( ".vml" )
 {
     // register XML namespaces
-    const Sequence< beans::Pair< OUString, sal_Int32 > > ids=
-        NamespaceIds::get();
-    for( sal_Int32 i=0; i<ids.getLength(); ++i )
-        maFastParser.registerNamespace( ids[i].Second );
+    registerNamespaces(maFastParser);
 }
 
 XmlFilterBase::XmlFilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
@@ -203,13 +207,25 @@ void XmlFilterBase::importDocumentProperties()
     xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() );
 }
 
+FastParser* XmlFilterBase::createParser() const
+{
+    FastParser* pParser = new FastParser(getComponentContext());
+    registerNamespaces(*pParser);
+    return pParser;
+}
+
 OUString XmlFilterBase::getFragmentPathFromFirstType( const OUString& rType )
 {
     // importRelations() caches the relations map for subsequence calls
     return importRelations( OUString() )->getFragmentPathFromFirstType( rType );
 }
 
-bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
+bool XmlFilterBase::importFragment( const rtl::Reference<FragmentHandler>& rxHandler )
+{
+    return importFragment(rxHandler, mxImpl->maFastParser);
+}
+
+bool XmlFilterBase::importFragment( const rtl::Reference<FragmentHandler>& rxHandler, FastParser& rParser )
 {
     OSL_ENSURE( rxHandler.is(), "XmlFilterBase::importFragment - missing fragment handler" );
     if( !rxHandler.is() )
@@ -263,8 +279,8 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r
         // own try/catch block for showing parser failure assertion with fragment path
         if( xInStrm.is() ) try
         {
-            mxImpl->maFastParser.setDocumentHandler( xDocHandler );
-            mxImpl->maFastParser.parseStream( xInStrm, aFragmentPath );
+            rParser.setDocumentHandler(xDocHandler);
+            rParser.parseStream(xInStrm, aFragmentPath);
             return true;
         }
         catch( Exception& )
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index abafb20..1f472c3 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -53,6 +53,7 @@ namespace oox { namespace core {
     class FilterBase;
     class FragmentHandler;
     class XmlFilterBase;
+    class FastParser;
 } }
 
 class ScDocument;
@@ -269,7 +270,10 @@ public:
 
     /** Imports a fragment using the passed fragment handler, which contains
         the full path to the fragment stream. */
-    bool                importOoxFragment( const ::rtl::Reference< ::oox::core::FragmentHandler >& rxHandler );
+    bool importOoxFragment( const rtl::Reference<oox::core::FragmentHandler>& rxHandler );
+
+    bool importOoxFragment( const rtl::Reference<oox::core::FragmentHandler>& rxHandler, oox::core::FastParser& rParser );
+
 
     // BIFF2-BIFF8 specific (MUST NOT be called in OOXML/BIFF12 filter) -------
 
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index e9471cb..81eb2ed 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -49,6 +49,7 @@
 #include "globstr.hrc"
 #include "calcconfig.hxx"
 
+#include <oox/core/fastparser.hxx>
 #include <comphelper/processfactory.hxx>
 #include <officecfg/Office/Calc.hxx>
 #include <salhelper/thread.hxx>
@@ -240,13 +241,17 @@ class WorkerThread : public salhelper::Thread
     WorkbookFragment& mrWorkbookHandler;
     size_t mnID;
     FragmentHandlerRef mxHandler;
+    boost::scoped_ptr<oox::core::FastParser> mxParser;
     osl::Mutex maMtxAction;
     osl::Condition maCondActionChanged;
     WorkerAction meAction;
 public:
     WorkerThread( WorkbookFragment& rWorkbookHandler, size_t nID ) :
         salhelper::Thread("sheet-import-worker-thread"),
-        mrWorkbookHandler(rWorkbookHandler), mnID(nID), meAction(None) {}
+        mrWorkbookHandler(rWorkbookHandler),
+        mnID(nID),
+        mxParser(rWorkbookHandler.getOoxFilter().createParser()),
+        meAction(None) {}
 
     virtual void execute()
     {
@@ -271,7 +276,7 @@ public:
 
 #if 0
             // TODO : This still deadlocks in the fast parser code.
-            mrWorkbookHandler.importOoxFragment(mxHandler);
+            mrWorkbookHandler.importOoxFragment(mxHandler, *mxParser);
 #else
             double val = rand() / static_cast<double>(RAND_MAX);
             val *= 1000000; // normalize to 1 second.
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 33270e5..66a51b4 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -961,11 +961,16 @@ XmlFilterBase& WorkbookHelper::getOoxFilter() const
     return mrBookGlob.getOoxFilter();
 }
 
-bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
+bool WorkbookHelper::importOoxFragment( const rtl::Reference<FragmentHandler>& rxHandler )
 {
     return getOoxFilter().importFragment( rxHandler );
 }
 
+bool WorkbookHelper::importOoxFragment( const rtl::Reference<FragmentHandler>& rxHandler, oox::core::FastParser& rParser )
+{
+    return getOoxFilter().importFragment(rxHandler, rParser);
+}
+
 // BIFF specific --------------------------------------------------------------
 
 BiffType WorkbookHelper::getBiff() const
commit 8e5fd4a15ae2c7d55842b1b768b7807a2d3a298e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 20:14:44 2013 -0500

    A bit of cleanup.
    
    Change-Id: I576a184ebc8422d760800c670f8d9070f66e9e78

diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 3416dc7..dddc29c 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -58,8 +58,6 @@ using ::com::sun::star::xml::dom::XDocumentBuilder;
 namespace oox {
 namespace core {
 
-// ============================================================================
-
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::container;
@@ -74,12 +72,6 @@ using utl::MediaDescriptor;
 using ::sax_fastparser::FSHelperPtr;
 using ::sax_fastparser::FastSerializerHelper;
 
-
-
-
-
-// ============================================================================
-
 namespace {
 
 bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
@@ -88,27 +80,6 @@ bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
     return (nSuffixPos >= 0) && rFragmentPath.match( rSuffix, nSuffixPos );
 }
 
-} // namespace
-
-// ============================================================================
-
-struct XmlFilterBaseImpl
-{
-    typedef RefMap< OUString, Relations > RelationsMap;
-
-    FastParser                     maFastParser;
-    const OUString                 maBinSuffix;
-    const OUString                 maVmlSuffix;
-    RelationsMap                   maRelationsMap;
-    TextFieldStack                 maTextFieldStack;
-
-    explicit            XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
-};
-
-// ----------------------------------------------------------------------------
-
-namespace {
-
 struct NamespaceIds: public rtl::StaticWithInit<
     Sequence< beans::Pair< OUString, sal_Int32 > >,
     NamespaceIds>
@@ -172,9 +143,20 @@ struct NamespaceIds: public rtl::StaticWithInit<
     }
 };
 
-}
+} // namespace
 
-// ----------------------------------------------------------------------------
+struct XmlFilterBaseImpl
+{
+    typedef RefMap< OUString, Relations > RelationsMap;
+
+    FastParser                     maFastParser;
+    const OUString                 maBinSuffix;
+    const OUString                 maVmlSuffix;
+    RelationsMap                   maRelationsMap;
+    TextFieldStack                 maTextFieldStack;
+
+    explicit            XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
+};
 
 XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
     maFastParser( rxContext ),
commit 136d57e9eb2a106ac4c22712027cc48ed6e4ad8d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 20:12:41 2013 -0500

    No indent on namespaces.
    
    Change-Id: I2639a51c2faa19373a335c28b160862435cd6dbe

diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 98c8886..3416dc7 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -107,70 +107,71 @@ struct XmlFilterBaseImpl
 
 // ----------------------------------------------------------------------------
 
-namespace
+namespace {
+
+struct NamespaceIds: public rtl::StaticWithInit<
+    Sequence< beans::Pair< OUString, sal_Int32 > >,
+    NamespaceIds>
 {
-    struct NamespaceIds: public rtl::StaticWithInit<
-        Sequence< beans::Pair< OUString, sal_Int32 > >,
-        NamespaceIds>
+    Sequence< beans::Pair< OUString, sal_Int32 > > operator()()
     {
-        Sequence< beans::Pair< OUString, sal_Int32 > > operator()()
-        {
-            static const char* const namespaceURIs[] = {
-                "http://www.w3.org/XML/1998/namespace",
-                "http://schemas.openxmlformats.org/package/2006/relationships",
-                "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
-                "http://schemas.openxmlformats.org/drawingml/2006/main",
-                "http://schemas.openxmlformats.org/drawingml/2006/diagram",
-                "http://schemas.openxmlformats.org/drawingml/2006/chart",
-                "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
-                "urn:schemas-microsoft-com:vml",
-                "urn:schemas-microsoft-com:office:office",
-                "urn:schemas-microsoft-com:office:word",
-                "urn:schemas-microsoft-com:office:excel",
-                "urn:schemas-microsoft-com:office:powerpoint",
-                "http://schemas.microsoft.com/office/2006/activeX",
-                "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
-                "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
-                "http://schemas.microsoft.com/office/excel/2006/main",
-                "http://schemas.openxmlformats.org/presentationml/2006/main",
-                "http://schemas.openxmlformats.org/markup-compatibility/2006",
-                "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
-                "http://schemas.microsoft.com/office/drawing/2008/diagram",
-                "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
-            };
-
-            static const sal_Int32 namespaceIds[] = {
-                NMSP_xml,
-                NMSP_packageRel,
-                NMSP_officeRel,
-                NMSP_dml,
-                NMSP_dmlDiagram,
-                NMSP_dmlChart,
-                NMSP_dmlChartDr,
-                NMSP_dmlSpreadDr,
-                NMSP_vml,
-                NMSP_vmlOffice,
-                NMSP_vmlWord,
-                NMSP_vmlExcel,
-                NMSP_vmlPowerpoint,
-                NMSP_xls,
-                NMSP_ppt,
-                NMSP_ax,
-                NMSP_xm,
-                NMSP_mce,
-                NMSP_mceTest,
-                NMSP_dsp,
-                NMSP_xlsExtLst
-            };
-
-            Sequence< beans::Pair< OUString, sal_Int32 > > aRet(STATIC_ARRAY_SIZE(namespaceIds));
-            for( sal_Int32 i=0; i<aRet.getLength(); ++i )
-                aRet[i] = make_Pair(
-                    OUString::createFromAscii(namespaceURIs[i]),
-                    namespaceIds[i]);
-            return aRet;
-        }
-    };
+        static const char* const namespaceURIs[] = {
+            "http://www.w3.org/XML/1998/namespace",
+            "http://schemas.openxmlformats.org/package/2006/relationships",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+            "http://schemas.openxmlformats.org/drawingml/2006/main",
+            "http://schemas.openxmlformats.org/drawingml/2006/diagram",
+            "http://schemas.openxmlformats.org/drawingml/2006/chart",
+            "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
+            "urn:schemas-microsoft-com:vml",
+            "urn:schemas-microsoft-com:office:office",
+            "urn:schemas-microsoft-com:office:word",
+            "urn:schemas-microsoft-com:office:excel",
+            "urn:schemas-microsoft-com:office:powerpoint",
+            "http://schemas.microsoft.com/office/2006/activeX",
+            "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+            "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
+            "http://schemas.microsoft.com/office/excel/2006/main",
+            "http://schemas.openxmlformats.org/presentationml/2006/main",
+            "http://schemas.openxmlformats.org/markup-compatibility/2006",
+            "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
+            "http://schemas.microsoft.com/office/drawing/2008/diagram",
+            "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
+        };
+
+        static const sal_Int32 namespaceIds[] = {
+            NMSP_xml,
+            NMSP_packageRel,
+            NMSP_officeRel,
+            NMSP_dml,
+            NMSP_dmlDiagram,
+            NMSP_dmlChart,
+            NMSP_dmlChartDr,
+            NMSP_dmlSpreadDr,
+            NMSP_vml,
+            NMSP_vmlOffice,
+            NMSP_vmlWord,
+            NMSP_vmlExcel,
+            NMSP_vmlPowerpoint,
+            NMSP_xls,
+            NMSP_ppt,
+            NMSP_ax,
+            NMSP_xm,
+            NMSP_mce,
+            NMSP_mceTest,
+            NMSP_dsp,
+            NMSP_xlsExtLst
+        };
+
+        Sequence< beans::Pair< OUString, sal_Int32 > > aRet(STATIC_ARRAY_SIZE(namespaceIds));
+        for( sal_Int32 i=0; i<aRet.getLength(); ++i )
+            aRet[i] = make_Pair(
+                OUString::createFromAscii(namespaceURIs[i]),
+                namespaceIds[i]);
+        return aRet;
+    }
+};
+
 }
 
 // ----------------------------------------------------------------------------
commit 0da598c5d7f2bedc8113567bccade3d2a9f8a0b1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 22 18:28:26 2013 -0500

    Add hook to optionally enable threaded sheet stream parsing.
    
    Threaded version still not working as the fast parser deadlocks during
    threaded parsing.
    
    Change-Id: I3d402a22a394d7d0d7edf96590ae039506928fde

diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index 30f0f34..e9471cb 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -51,6 +51,12 @@
 
 #include <comphelper/processfactory.hxx>
 #include <officecfg/Office/Calc.hxx>
+#include <salhelper/thread.hxx>
+#include <osl/conditn.hxx>
+
+#include <queue>
+#include <boost/scoped_ptr.hpp>
+
 #include "oox/ole/vbaproject.hxx"
 
 namespace oox {
@@ -194,6 +200,189 @@ const RecordInfo* WorkbookFragment::getRecordInfos() const
     return spRecInfos;
 }
 
+namespace {
+
+class WorkerThread;
+
+typedef std::pair<WorksheetGlobalsRef, FragmentHandlerRef> SheetFragmentHandler;
+typedef std::vector<SheetFragmentHandler> SheetFragmentVector;
+typedef rtl::Reference<WorkerThread> WorkerThreadRef;
+
+struct WorkerThreadData
+{
+    osl::Mutex maMtx;
+    std::vector<WorkerThreadRef> maThreads;
+};
+
+struct IdleWorkerThreadData
+{
+    osl::Mutex maMtx;
+    osl::Condition maCondAdded;
+    std::queue<WorkerThread*> maThreads;
+};
+
+struct
+{
+    boost::scoped_ptr<WorkerThreadData> mpWorkerThreads;
+    boost::scoped_ptr<IdleWorkerThreadData> mpIdleThreads;
+
+} aThreadGlobals;
+
+enum WorkerAction
+{
+    None = 0,
+    TerminateThread,
+    Work
+};
+
+class WorkerThread : public salhelper::Thread
+{
+    WorkbookFragment& mrWorkbookHandler;
+    size_t mnID;
+    FragmentHandlerRef mxHandler;
+    osl::Mutex maMtxAction;
+    osl::Condition maCondActionChanged;
+    WorkerAction meAction;
+public:
+    WorkerThread( WorkbookFragment& rWorkbookHandler, size_t nID ) :
+        salhelper::Thread("sheet-import-worker-thread"),
+        mrWorkbookHandler(rWorkbookHandler), mnID(nID), meAction(None) {}
+
+    virtual void execute()
+    {
+        announceIdle();
+
+        // Keep looping until the terminate request is set.
+        for (maCondActionChanged.wait(); true; maCondActionChanged.wait())
+        {
+            osl::MutexGuard aGuard(maMtxAction);
+            if (!maCondActionChanged.check())
+                // Wait again.
+                continue;
+
+            maCondActionChanged.reset();
+
+            if (meAction == TerminateThread)
+                // End the thread.
+                return;
+
+            if (meAction != Work)
+                continue;
+
+#if 0
+            // TODO : This still deadlocks in the fast parser code.
+            mrWorkbookHandler.importOoxFragment(mxHandler);
+#else
+            double val = rand() / static_cast<double>(RAND_MAX);
+            val *= 1000000; // normalize to 1 second.
+            val *= 1.5; // inflate it a bit.
+            usleep(val); // pretend to be working while asleep.
+#endif
+            announceIdle();
+        }
+    }
+
+    void announceIdle()
+    {
+        // Set itself idle to receive a new task from the main thread.
+        osl::MutexGuard aGuard(aThreadGlobals.mpIdleThreads->maMtx);
+        aThreadGlobals.mpIdleThreads->maThreads.push(this);
+        aThreadGlobals.mpIdleThreads->maCondAdded.set();
+    }
+
+    void terminate()
+    {
+        osl::MutexGuard aGuard(maMtxAction);
+        meAction = TerminateThread;
+        maCondActionChanged.set();
+    }
+
+    void assign( const FragmentHandlerRef& rHandler )
+    {
+        osl::MutexGuard aGuard(maMtxAction);
+        mxHandler = rHandler;
+        meAction = Work;
+        maCondActionChanged.set();
+    }
+};
+
+void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets )
+{
+#if 0 // threaded version
+    size_t nThreadCount = 3;
+    if (nThreadCount > rSheets.size())
+        nThreadCount = rSheets.size();
+
+    // Create new thread globals.
+    aThreadGlobals.mpWorkerThreads.reset(new WorkerThreadData);
+    aThreadGlobals.mpIdleThreads.reset(new IdleWorkerThreadData);
+
+    SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end();
+
+    {
+        // Initialize worker threads.
+        osl::MutexGuard aGuard(aThreadGlobals.mpWorkerThreads->maMtx);
+        for (size_t i = 0; i < nThreadCount; ++i)
+        {
+            WorkerThreadRef pThread(new WorkerThread(rWorkbookHandler, i));
+            aThreadGlobals.mpWorkerThreads->maThreads.push_back(pThread);
+            pThread->launch();
+        }
+    }
+
+    for (aThreadGlobals.mpIdleThreads->maCondAdded.wait(); true; aThreadGlobals.mpIdleThreads->maCondAdded.wait())
+    {
+        osl::MutexGuard aGuard(aThreadGlobals.mpIdleThreads->maMtx);
+        if (!aThreadGlobals.mpIdleThreads->maCondAdded.check())
+            // Wait again.
+            continue;
+
+        aThreadGlobals.mpIdleThreads->maCondAdded.reset();
+
+        // Assign work to all idle threads.
+        while (!aThreadGlobals.mpIdleThreads->maThreads.empty())
+        {
+            if (it == itEnd)
+                break;
+
+            WorkerThread* p = aThreadGlobals.mpIdleThreads->maThreads.front();
+            aThreadGlobals.mpIdleThreads->maThreads.pop();
+            p->assign(it->second);
+            ++it;
+        }
+
+        if (it == itEnd)
+            // Finished!  Exit the loop.
+            break;
+    }
+
+    {
+        // Terminate all worker threads.
+        osl::MutexGuard aGuard(aThreadGlobals.mpWorkerThreads->maMtx);
+        for (size_t i = 0, n = aThreadGlobals.mpWorkerThreads->maThreads.size(); i < n; ++i)
+        {
+            WorkerThreadRef pWorker = aThreadGlobals.mpWorkerThreads->maThreads[i];
+            pWorker->terminate();
+            if (pWorker.is())
+                pWorker->join();
+        }
+    }
+
+    // Delete all thread globals.
+    aThreadGlobals.mpWorkerThreads.reset();
+    aThreadGlobals.mpIdleThreads.reset();
+
+#else // non-threaded version
+    for( SheetFragmentVector::iterator it = rSheets.begin(), itEnd = rSheets.end(); it != itEnd; ++it)
+    {
+        // import the sheet fragment
+        rWorkbookHandler.importOoxFragment(it->second);
+    }
+#endif
+}
+
+}
+
 void WorkbookFragment::finalizeImport()
 {
     ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
@@ -229,8 +418,6 @@ void WorkbookFragment::finalizeImport()
         fragments for all sheets that are needed before the cell formulas are
         loaded. Additionally, the instances of the WorkbookGlobals structures
         have to be stored for every sheet. */
-    typedef ::std::pair< WorksheetGlobalsRef, FragmentHandlerRef > SheetFragmentHandler;
-    typedef ::std::vector< SheetFragmentHandler > SheetFragmentVector;
     SheetFragmentVector aSheetFragments;
     std::vector<WorksheetHelper*> maHelpers;
     WorksheetBuffer& rWorksheets = getWorksheets();
@@ -315,11 +502,7 @@ void WorkbookFragment::finalizeImport()
     }
 
     // load all worksheets
-    for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt )
-    {
-        // import the sheet fragment
-        importOoxFragment( aIt->second );
-    }
+    importSheetFragments(*this, aSheetFragments);
 
     for( std::vector<WorksheetHelper*>::iterator aIt = maHelpers.begin(), aEnd = maHelpers.end(); aIt != aEnd; ++aIt )
     {


More information about the Libreoffice-commits mailing list