summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/qa/desktop_lib/test_desktop_lib.cxx5
-rw-r--r--desktop/source/lib/init.cxx18
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h3
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.hxx9
-rw-r--r--include/comphelper/lok.hxx2
-rw-r--r--ucb/source/ucp/webdav-curl/CurlSession.cxx43
-rw-r--r--ucb/source/ucp/webdav-curl/SerfLockStore.cxx35
-rw-r--r--ucb/source/ucp/webdav-curl/SerfLockStore.hxx12
-rw-r--r--ucb/source/ucp/webdav-curl/ucpdav1.component4
9 files changed, 117 insertions, 14 deletions
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 298e5a5d7a9b..4a09b10931f6 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -3594,11 +3594,12 @@ void DesktopLOKTest::testABI()
CPPUNIT_ASSERT_EQUAL(classOffset(18), offsetof(struct _LibreOfficeKitClass, startURP));
CPPUNIT_ASSERT_EQUAL(classOffset(19), offsetof(struct _LibreOfficeKitClass, stopURP));
CPPUNIT_ASSERT_EQUAL(classOffset(20), offsetof(struct _LibreOfficeKitClass, joinThreads));
- CPPUNIT_ASSERT_EQUAL(classOffset(21), offsetof(struct _LibreOfficeKitClass, setForkedChild));
+ CPPUNIT_ASSERT_EQUAL(classOffset(21), offsetof(struct _LibreOfficeKitClass, startThreads));
+ CPPUNIT_ASSERT_EQUAL(classOffset(22), offsetof(struct _LibreOfficeKitClass, setForkedChild));
// When extending LibreOfficeKit with a new function pointer, add new assert for the offsetof the
// new function pointer and bump this assert for the size of the class.
- CPPUNIT_ASSERT_EQUAL(classOffset(22), sizeof(struct _LibreOfficeKitClass));
+ CPPUNIT_ASSERT_EQUAL(classOffset(23), sizeof(struct _LibreOfficeKitClass));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(0), offsetof(struct _LibreOfficeKitDocumentClass, destroy));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(1), offsetof(struct _LibreOfficeKitDocumentClass, saveAs));
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f00edb9ec9c9..86f0efda8857 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2602,6 +2602,8 @@ static void lo_stopURP(LibreOfficeKit* pThis, void* pSendURPToLOContext);
static int lo_joinThreads(LibreOfficeKit* pThis);
+static void lo_startThreads(LibreOfficeKit* pThis);
+
static void lo_setForkedChild(LibreOfficeKit* pThis, bool bIsChild);
static void lo_runLoop(LibreOfficeKit* pThis,
@@ -2649,6 +2651,7 @@ LibLibreOffice_Impl::LibLibreOffice_Impl()
m_pOfficeClass->startURP = lo_startURP;
m_pOfficeClass->stopURP = lo_stopURP;
m_pOfficeClass->joinThreads = lo_joinThreads;
+ m_pOfficeClass->startThreads = lo_startThreads;
m_pOfficeClass->setForkedChild = lo_setForkedChild;
gOfficeClass = m_pOfficeClass;
@@ -3399,6 +3402,12 @@ static int lo_joinThreads(LibreOfficeKit* /* pThis */)
if (joinable && !joinable->joinThreads())
return 0;
+ auto ucpWebdav = xContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.ucb.WebDAVManager", xContext);
+ joinable = dynamic_cast<comphelper::LibreOfficeKit::ThreadJoinable *>(ucpWebdav.get());
+ if (joinable && !joinable->joinThreads())
+ return 0;
+
// Ensure configmgr's write thread is down
css::uno::Reference< css::util::XFlushable >(
css::configuration::theDefaultProvider::get(
@@ -3408,6 +3417,15 @@ static int lo_joinThreads(LibreOfficeKit* /* pThis */)
return 1;
}
+static void lo_startThreads(LibreOfficeKit* /* pThis */)
+{
+ auto ucpWebdav = xContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.ucb.WebDAVManager", xContext);
+ auto joinable = dynamic_cast<comphelper::LibreOfficeKit::ThreadJoinable *>(ucpWebdav.get());
+ if (joinable)
+ joinable->startThreads();
+}
+
static void lo_setForkedChild(LibreOfficeKit* /* pThis */, bool bIsChild)
{
comphelper::LibreOfficeKit::setForkedChild(bIsChild);
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index f57c7ad32843..2a0df3348f8d 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -144,6 +144,9 @@ struct _LibreOfficeKitClass
/// @see lok::Office::joinThreads
int (*joinThreads)(LibreOfficeKit* pThis);
+ /// @see lok::Office::startThreads
+ void (*startThreads)(LibreOfficeKit* pThis);
+
/// @see lok::Office::setForkedChild
void (*setForkedChild)(LibreOfficeKit* pThis, bool bIsChild);
};
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index af9ccd12ab2f..14ad6a86f913 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -1224,6 +1224,15 @@ public:
}
/**
+ * Starts all threads that are necessary to continue working
+ * after a joinThreads().
+ */
+ void startThreads()
+ {
+ mpThis->pClass->startThreads(mpThis);
+ }
+
+ /**
* Informs that this process is either a parent, or a child
* process post-fork, allowing improved resource sharing.
*/
diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx
index 555b749fa6a1..f998c12dedc3 100644
--- a/include/comphelper/lok.hxx
+++ b/include/comphelper/lok.hxx
@@ -26,6 +26,8 @@ class COMPHELPER_DLLPUBLIC SAL_LOPLUGIN_ANNOTATE("crosscast") ThreadJoinable
public:
/// shutdown and join threads, @returns true on success
virtual bool joinThreads() = 0;
+ /// restart any required threads, usually are demand-restarted
+ virtual void startThreads() {}
};
// Functions to be called only from the LibreOfficeKit implementation in desktop, not from other
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index e60bd6ef1d36..a80c19f6d690 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -14,9 +14,13 @@
#include "UCBDeadPropertyValue.hxx"
#include "webdavresponseparser.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <comphelper/processfactory.hxx>
#include <comphelper/attributelist.hxx>
#include <comphelper/scopeguard.hxx>
#include <comphelper/string.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/supportsservice.hxx>
#include <o3tl/safeint.hxx>
#include <o3tl/string_view.hxx>
@@ -26,6 +30,7 @@
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/io/Pipe.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/io/SequenceInputStream.hpp>
#include <com/sun/star/io/SequenceOutputStream.hpp>
#include <com/sun/star/xml/sax/Writer.hpp>
@@ -2430,4 +2435,42 @@ auto CurlSession::NonInteractive_UNLOCK(OUString const& rURI) -> void
} // namespace http_dav_ucp
+namespace
+{
+/// Manage lifecycle of global DAV worker threads
+class WebDAVManager : public cppu::WeakImplHelper<css::lang::XServiceInfo>,
+ public comphelper::LibreOfficeKit::ThreadJoinable
+{
+public:
+ WebDAVManager() {}
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.WebDAVManager";
+ }
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return { "com.sun.star.ucb.WebDAVManager" };
+ }
+
+ // comphelper::LibreOfficeKit::ThreadJoinable
+ virtual bool joinThreads() override { return g_Init.LockStore.joinThreads(); }
+
+ virtual void startThreads() override { g_Init.LockStore.startThreads(); }
+};
+
+} // anonymous namespace
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+ucb_webdav_manager_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new WebDAVManager());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
index 6d7b89e9e687..cfa6f666b056 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
@@ -101,10 +101,8 @@ SerfLockStore::~SerfLockStore()
}
}
-void SerfLockStore::startTicker()
+void SerfLockStore::startTicker(std::unique_lock<std::mutex> & /* rGuard is held */)
{
- std::unique_lock aGuard( m_aMutex );
-
if ( !m_pTickerThread.is() )
{
m_pTickerThread = new TickerThread( *this );
@@ -112,7 +110,6 @@ void SerfLockStore::startTicker()
}
}
-
void SerfLockStore::stopTicker(std::unique_lock<std::mutex> & rGuard)
{
rtl::Reference<TickerThread> pTickerThread;
@@ -122,6 +119,7 @@ void SerfLockStore::stopTicker(std::unique_lock<std::mutex> & rGuard)
m_pTickerThread->finish(); // needs mutex
// the TickerThread may run refreshLocks() at most once after this
pTickerThread = m_pTickerThread;
+
m_pTickerThread.clear();
}
@@ -133,6 +131,25 @@ void SerfLockStore::stopTicker(std::unique_lock<std::mutex> & rGuard)
}
}
+bool SerfLockStore::joinThreads()
+{
+ std::unique_lock aGuard(m_aMutex);
+ // FIXME: cure could be worse than the problem; we don't
+ // want to block on a long-standing webdav lock refresh request.
+ // perhaps we should timeout on a condition instead if a request
+ // is in progress.
+ if (m_pTickerThread.is())
+ stopTicker(aGuard);
+ return true;
+}
+
+void SerfLockStore::startThreads()
+{
+ std::unique_lock aGuard( m_aMutex );
+ if (!m_aLockInfoMap.empty())
+ startTicker(aGuard);
+}
+
OUString const*
SerfLockStore::getLockTokenForURI(OUString const& rURI, css::ucb::Lock const*const pLock)
{
@@ -175,14 +192,12 @@ void SerfLockStore::addLock( const OUString& rURI,
sal_Int32 nLastChanceToSendRefreshRequest )
{
assert(rURI.startsWith("http://") || rURI.startsWith("https://"));
- {
- std::unique_lock aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
- m_aLockInfoMap[ rURI ]
- = LockInfo(sToken, rLock, xSession, nLastChanceToSendRefreshRequest);
- }
+ m_aLockInfoMap[ rURI ]
+ = LockInfo(sToken, rLock, xSession, nLastChanceToSendRefreshRequest);
- startTicker();
+ startTicker(aGuard);
}
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
index 8b54901e1fb8..08a88746b0d0 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
@@ -26,6 +26,7 @@
#include <rtl/ustring.hxx>
#include <com/sun/star/ucb/Lock.hpp>
#include <utility>
+#include <comphelper/lok.hxx>
#include "CurlSession.hxx"
@@ -57,7 +58,7 @@ struct LockInfo
typedef std::map< OUString, LockInfo > LockInfoMap;
-class SerfLockStore
+class SerfLockStore : public comphelper::LibreOfficeKit::ThreadJoinable
{
std::mutex m_aMutex;
rtl::Reference< TickerThread > m_pTickerThread;
@@ -81,9 +82,16 @@ public:
void refreshLocks();
+ void joinThread();
+ void restartThread();
+
+ // comphelper::LibreOfficeKit::ThreadJoinable
+ virtual bool joinThreads() override;
+ virtual void startThreads() override;
+
private:
void removeLockImpl(std::unique_lock<std::mutex> & rGuard, const OUString& rURI);
- void startTicker();
+ void startTicker(std::unique_lock<std::mutex> & rGuard);
void stopTicker(std::unique_lock<std::mutex> & rGuard);
};
diff --git a/ucb/source/ucp/webdav-curl/ucpdav1.component b/ucb/source/ucp/webdav-curl/ucpdav1.component
index bb16e3b3979d..678e860c1178 100644
--- a/ucb/source/ucp/webdav-curl/ucpdav1.component
+++ b/ucb/source/ucp/webdav-curl/ucpdav1.component
@@ -23,4 +23,8 @@
constructor="ucb_webdav_ContentProvider_get_implementation">
<service name="com.sun.star.ucb.WebDAVContentProvider"/>
</implementation>
+ <implementation name="com.sun.star.comp.WebDAVManager"
+ constructor="ucb_webdav_manager_get_implementation" single-instance="true">
+ <service name="com.sun.star.ucb.WebDAVManager"/>
+ </implementation>
</component>