[Libreoffice-commits] core.git: filter/qa filter/source

Stephan Bergmann sbergman at redhat.com
Mon Sep 11 15:58:52 UTC 2017


 filter/qa/cppunit/xslt-test.cxx                 |   44 +++++++++++++++---------
 filter/source/xsltfilter/LibXSLTTransformer.cxx |   21 +++++++++--
 filter/source/xsltfilter/LibXSLTTransformer.hxx |    3 +
 3 files changed, 48 insertions(+), 20 deletions(-)

New commits:
commit cd8aeed1569222edd8bfd05d9d833f74b679fcd0
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Sep 11 17:58:13 2017 +0200

    Fix data races during CppunitTest_filter_xslt
    
    Change-Id: I140ac8a24326959ba341adddbbf505ff16616283

diff --git a/filter/qa/cppunit/xslt-test.cxx b/filter/qa/cppunit/xslt-test.cxx
index 65de2667e493..7354cc85374f 100644
--- a/filter/qa/cppunit/xslt-test.cxx
+++ b/filter/qa/cppunit/xslt-test.cxx
@@ -7,7 +7,11 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <sal/config.h>
+
+#include <condition_variable>
 #include <limits>
+#include <mutex>
 
 #include <cppunit/TestAssert.h>
 #include <cppunit/TestFixture.h>
@@ -19,7 +23,6 @@
 #include <rtl/ref.hxx>
 
 #include <osl/file.hxx>
-#include <osl/thread.h>
 
 #include <com/sun/star/beans/NamedValue.hpp>
 #include <com/sun/star/io/XStreamListener.hpp>
@@ -51,22 +54,37 @@ public:
     CPPUNIT_TEST_SUITE_END();
 };
 
-struct Listener : public ::cppu::WeakImplHelper<io::XStreamListener>
+class Listener : public ::cppu::WeakImplHelper<io::XStreamListener>
 {
-    bool m_bDone;
-
+public:
     Listener() : m_bDone(false) {}
 
+    void wait() {
+        std::unique_lock<std::mutex> g(m_mutex);
+        m_cond.wait(g, [this]() { return m_bDone; });
+    }
+
+private:
+    std::mutex m_mutex;
+    std::condition_variable m_cond;
+    bool m_bDone;
+
     virtual void SAL_CALL disposing(const lang::EventObject&) throw() override {}
-    virtual void SAL_CALL started() throw() override { m_bDone = false; }
-    virtual void SAL_CALL closed() throw() override { m_bDone = true; }
-    virtual void SAL_CALL terminated() throw() override { m_bDone = true; }
+    virtual void SAL_CALL started() throw() override {}
+    virtual void SAL_CALL closed() throw() override { notifyDone(); }
+    virtual void SAL_CALL terminated() throw() override { notifyDone(); }
     virtual void SAL_CALL error(const uno::Any& e) override
     {
-        m_bDone = true; // set on error too, otherwise main thread waits forever
+        notifyDone(); // set on error too, otherwise main thread waits forever
         SAL_WARN("filter.xslt", "exception " << e);
         CPPUNIT_FAIL("exception while in XSLT");
     }
+
+    void notifyDone() {
+        std::unique_lock<std::mutex> g(m_mutex);
+        m_bDone = true;
+        m_cond.notify_all();
+    }
 };
 
 void XsltFilterTest::testXsltCopyNew()
@@ -109,10 +127,7 @@ void XsltFilterTest::testXsltCopyNew()
 
     xXslt->start();
 
-    TimeValue delay;
-    delay.Seconds = 0;
-    delay.Nanosec = 1000000;
-    while (!xListener->m_bDone) { osl_waitThread(&delay); }
+    xListener->wait();
 
     xIn->closeInput();
     xOut->closeOutput();
@@ -171,10 +186,7 @@ void XsltFilterTest::testXsltCopyOld()
 
     xXslt->start();
 
-    TimeValue delay;
-    delay.Seconds = 0;
-    delay.Nanosec = 1000000;
-    while (!xListener->m_bDone) { osl_waitThread(&delay); }
+    xListener->wait();
 
     xIn->closeInput();
     xOut->closeOutput();
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx b/filter/source/xsltfilter/LibXSLTTransformer.cxx
index 33719eb5e4c6..35d3dfcc8242 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.cxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -298,7 +298,12 @@ namespace XSLT
         std::unique_ptr<OleHandler> oh(new OleHandler(m_transformer->getComponentContext()));
         if (styleSheet)
         {
-            m_tcontext = xsltNewTransformContext(styleSheet, doc);
+            xsltTransformContextPtr tcontext = xsltNewTransformContext(
+                styleSheet, doc);
+            {
+                std::unique_lock<std::mutex> g(m_mutex);
+                m_tcontext = tcontext;
+            }
             oh->registercontext(m_tcontext);
             xsltQuoteUserParams(m_tcontext, &params[0]);
             result = xsltApplyStylesheetUser(styleSheet, doc, nullptr, nullptr, nullptr,
@@ -331,7 +336,10 @@ namespace XSLT
         oh.reset();
         xsltFreeStylesheet(styleSheet);
         xsltFreeTransformContext(m_tcontext);
-        m_tcontext = nullptr;
+        {
+            std::unique_lock<std::mutex> g(m_mutex);
+            m_tcontext = nullptr;
+        }
         xmlFreeDoc(doc);
         xmlFreeDoc(result);
     }
@@ -354,12 +362,17 @@ namespace XSLT
 
     void Reader::forceStateStopped()
     {
-        if (!m_tcontext)
+        xsltTransformContextPtr tcontext;
+        {
+            std::unique_lock<std::mutex> g(m_mutex);
+            tcontext = m_tcontext;
+        }
+        if (!tcontext)
             return;
         //tdf#100057 If we force a cancel, libxslt will of course just keep on going unless something
         //tells it to stop. Here we force the stopped state so that libxslt will stop processing
         //and so Reader::execute will complete and we can join cleanly
-        m_tcontext->state = XSLT_STATE_STOPPED;
+        tcontext->state = XSLT_STATE_STOPPED;
     }
 
     Reader::~Reader()
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx b/filter/source/xsltfilter/LibXSLTTransformer.hxx
index beb500f7faa5..e65820b1fd99 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.hxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx
@@ -12,6 +12,7 @@
 
 #include <list>
 #include <map>
+#include <mutex>
 
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -71,6 +72,8 @@ namespace XSLT
         LibXSLTTransformer* m_transformer;
         Sequence<sal_Int8> m_readBuf;
         Sequence<sal_Int8> m_writeBuf;
+
+        std::mutex m_mutex;
         xsltTransformContextPtr m_tcontext;
 
         virtual void execute() override;


More information about the Libreoffice-commits mailing list