diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-09-11 17:58:13 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-09-11 17:58:13 +0200 |
commit | cd8aeed1569222edd8bfd05d9d833f74b679fcd0 (patch) | |
tree | a0b21dc5f77625ac4b4395f355a53799cd0bf07d | |
parent | 2c7d421a3cacb602aabc89c5e49351ae4a5f7846 (diff) |
Fix data races during CppunitTest_filter_xslt
Change-Id: I140ac8a24326959ba341adddbbf505ff16616283
-rw-r--r-- | filter/qa/cppunit/xslt-test.cxx | 44 | ||||
-rw-r--r-- | filter/source/xsltfilter/LibXSLTTransformer.cxx | 21 | ||||
-rw-r--r-- | filter/source/xsltfilter/LibXSLTTransformer.hxx | 3 |
3 files changed, 48 insertions, 20 deletions
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; |