[Libreoffice-commits] core.git: Branch 'libreoffice-5-2' - filter/source

Caolán McNamara caolanm at redhat.com
Mon May 30 19:49:57 UTC 2016


 filter/source/xsltfilter/LibXSLTTransformer.cxx |   26 ++++++---
 filter/source/xsltfilter/LibXSLTTransformer.hxx |   69 +++++++++++-------------
 2 files changed, 53 insertions(+), 42 deletions(-)

New commits:
commit bce5cdcc7f59da19c063205c6c79fc30874cb5ee
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon May 30 17:47:06 2016 +0100

    Resolves: tdf#100057 force libxslt to give up when we cancel a transformation
    
    we're already using libxslt internals, so using XSLT_STATE_STOPPED isn't an
    additional exposure
    
    This probably isn't all that useful to the original reporter in terms of
    importing useful data, but it does turn a hopeless situation into something
    that can be cancelled.
    
    Change-Id: I08e9a1dcd9ee78e1804faec500bbcca36a546988
    (cherry picked from commit 2805adb0d3cf68d7def01a93bf07fb2e8121ec10)

diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx b/filter/source/xsltfilter/LibXSLTTransformer.cxx
index 3dbe7a4..55f1920 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.cxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -203,7 +203,8 @@ namespace XSLT
 
     Reader::Reader(LibXSLTTransformer* transformer) :
         Thread("LibXSLTTransformer"), m_transformer(transformer),
-        m_readBuf(INPUT_BUFFER_SIZE), m_writeBuf(OUTPUT_BUFFER_SIZE)
+        m_readBuf(INPUT_BUFFER_SIZE), m_writeBuf(OUTPUT_BUFFER_SIZE),
+        m_tcontext(nullptr)
     {
         LIBXML_TEST_VERSION;
     }
@@ -288,7 +289,6 @@ namespace XSLT
         xsltStylesheetPtr styleSheet = xsltParseStylesheetFile(
                 reinterpret_cast<const xmlChar *>(m_transformer->getStyleSheetURL().getStr()));
         xmlDocPtr result = nullptr;
-        xsltTransformContextPtr tcontext = nullptr;
         exsltRegisterAll();
         registerExtensionModule();
 #ifdef DEBUG_FILTER_LIBXSLTTRANSFORMER
@@ -298,11 +298,11 @@ namespace XSLT
         std::unique_ptr<OleHandler> oh(new OleHandler(m_transformer->getComponentContext()));
         if (styleSheet)
             {
-                tcontext = xsltNewTransformContext(styleSheet, doc);
-                tcontext->_private = static_cast<void *> (oh.get());
-                xsltQuoteUserParams(tcontext, &params[0]);
+                m_tcontext = xsltNewTransformContext(styleSheet, doc);
+                m_tcontext->_private = static_cast<void *> (oh.get());
+                xsltQuoteUserParams(m_tcontext, &params[0]);
                 result = xsltApplyStylesheetUser(styleSheet, doc, nullptr, nullptr, nullptr,
-                        tcontext);
+                                                 m_tcontext);
             }
 
         if (result)
@@ -330,7 +330,8 @@ namespace XSLT
         closeOutput();
         oh.reset();
         xsltFreeStylesheet(styleSheet);
-        xsltFreeTransformContext(tcontext);
+        xsltFreeTransformContext(m_tcontext);
+        m_tcontext = nullptr;
         xmlFreeDoc(doc);
         xmlFreeDoc(result);
     }
@@ -351,6 +352,16 @@ namespace XSLT
 
     }
 
+    void Reader::forceStateStopped()
+    {
+        if (!m_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;
+    }
+
     Reader::~Reader()
     {
     }
@@ -455,6 +466,7 @@ namespace XSLT
         if (m_Reader.is())
         {
             m_Reader->terminate();
+            m_Reader->forceStateStopped();
             m_Reader->join();
         }
         m_Reader.clear();
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx b/filter/source/xsltfilter/LibXSLTTransformer.hxx
index d276018..9c4485b 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.hxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx
@@ -47,6 +47,36 @@ using ::std::map;
 namespace XSLT
 {
 
+    class LibXSLTTransformer;
+
+    /*
+     * Reader provides a worker thread to perform the actual transformation.
+     * It pipes the streams provided by a LibXSLTTransformer
+     * instance through libxslt.
+     */
+    class Reader : public salhelper::Thread
+    {
+    public:
+        Reader(LibXSLTTransformer* transformer);
+        int SAL_CALL read(char * buffer, int len);
+        int SAL_CALL write(const char * buffer, int len);
+        void forceStateStopped();
+        int SAL_CALL closeOutput();
+
+    private:
+        virtual ~Reader();
+
+        static const sal_Int32 OUTPUT_BUFFER_SIZE;
+        static const sal_Int32 INPUT_BUFFER_SIZE;
+        LibXSLTTransformer* m_transformer;
+        Sequence<sal_Int8> m_readBuf;
+        Sequence<sal_Int8> m_writeBuf;
+        xsltTransformContextPtr m_tcontext;
+
+        virtual void execute() override;
+        static void SAL_CALL registerExtensionModule();
+    };
+
     /*
      * LibXSLTTransformer provides an transforming pipe service to XSLTFilter.
      *
@@ -85,13 +115,14 @@ namespace XSLT
 
         ::std::map<const char *, OString> m_parameters;
 
-        rtl::Reference< salhelper::Thread > m_Reader;
+        rtl::Reference<Reader> m_Reader;
 
     protected:
         virtual ~LibXSLTTransformer() {
             if (m_Reader.is()) {
-                    m_Reader->terminate();
-                    m_Reader->join();
+                m_Reader->terminate();
+                m_Reader->forceStateStopped();
+                m_Reader->join();
             }
         }
 
@@ -144,39 +175,7 @@ namespace XSLT
         }
 
     };
-
-    /*
-     * Reader provides a worker thread to perform the actual transformation.
-     * It pipes the streams provided by a LibXSLTTransformer
-     * instance through libxslt.
-     */
-    class Reader : public salhelper::Thread
-    {
-    public:
-        Reader(LibXSLTTransformer* transformer);
-        int SAL_CALL
-        read(char * buffer, int len);
-        int SAL_CALL
-        write(const char * buffer, int len);
-        int SAL_CALL
-        closeOutput();
-
-    private:
-        virtual
-        ~Reader();
-
-        static const sal_Int32 OUTPUT_BUFFER_SIZE;
-        static const sal_Int32 INPUT_BUFFER_SIZE;
-        LibXSLTTransformer* m_transformer;
-        Sequence<sal_Int8> m_readBuf;
-        Sequence<sal_Int8> m_writeBuf;
-
-        virtual void execute() override;
-        static void SAL_CALL registerExtensionModule();
-    };
-
 }
-;
 
 #endif // INCLUDED_FILTER_SOURCE_XSLTFILTER_LIBXSLTTRANSFORMER_HXX
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list