summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2017-09-11 17:58:13 +0200
committerStephan Bergmann <sbergman@redhat.com>2017-09-11 17:58:13 +0200
commitcd8aeed1569222edd8bfd05d9d833f74b679fcd0 (patch)
treea0b21dc5f77625ac4b4395f355a53799cd0bf07d /filter
parent2c7d421a3cacb602aabc89c5e49351ae4a5f7846 (diff)
Fix data races during CppunitTest_filter_xslt
Change-Id: I140ac8a24326959ba341adddbbf505ff16616283
Diffstat (limited to 'filter')
-rw-r--r--filter/qa/cppunit/xslt-test.cxx44
-rw-r--r--filter/source/xsltfilter/LibXSLTTransformer.cxx21
-rw-r--r--filter/source/xsltfilter/LibXSLTTransformer.hxx3
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, &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;