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 <sberg...@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, ¶ms[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; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits