From 09619742df11641c4f53b00f46ebe85496f1a316 Mon Sep 17 00:00:00 2001 From: sb Date: Mon, 4 Oct 2010 13:59:08 +0200 Subject: sb133: #i114705# for performance reasons, call configmgr::writeModFile asynchronously --- configmgr/source/components.cxx | 81 +++++++++++++++++++++++++++++- configmgr/source/components.hxx | 8 +++ configmgr/source/configurationprovider.cxx | 16 +++++- 3 files changed, 103 insertions(+), 2 deletions(-) (limited to 'configmgr') diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index cc5ea1e1e739..d1ffa8629a5f 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -29,6 +29,7 @@ #include "sal/config.h" #include +#include #include #include "com/sun/star/beans/Optional.hpp" @@ -43,8 +44,11 @@ #include "com/sun/star/uno/RuntimeException.hpp" #include "com/sun/star/uno/XComponentContext.hpp" #include "com/sun/star/uno/XInterface.hpp" +#include "osl/conditn.hxx" #include "osl/diagnose.h" #include "osl/file.hxx" +#include "osl/mutex.hxx" +#include "osl/thread.hxx" #include "rtl/bootstrap.hxx" #include "rtl/logfile.h" #include "rtl/ref.hxx" @@ -53,10 +57,12 @@ #include "rtl/ustring.h" #include "rtl/ustring.hxx" #include "sal/types.h" +#include "salhelper/simplereferenceobject.hxx" #include "additions.hxx" #include "components.hxx" #include "data.hxx" +#include "lock.hxx" #include "modifications.hxx" #include "node.hxx" #include "nodemap.hxx" @@ -148,6 +154,63 @@ static Components * singleton = 0; } +class Components::WriteThread: + public osl::Thread, public salhelper::SimpleReferenceObject +{ +public: + static void * operator new(std::size_t size) + { return Thread::operator new(size); } + + static void operator delete(void * pointer) + { Thread::operator delete(pointer); } + + WriteThread( + rtl::Reference< WriteThread > * reference, Components & components, + rtl::OUString const & url, Data const & data); + + void flush() { delay_.set(); } + +private: + virtual ~WriteThread() {} + + virtual void SAL_CALL run(); + + rtl::Reference< WriteThread > * reference_; + Components & components_; + rtl::OUString url_; + Data const & data_; + osl::Condition delay_; +}; + +Components::WriteThread::WriteThread( + rtl::Reference< WriteThread > * reference, Components & components, + rtl::OUString const & url, Data const & data): + reference_(reference), components_(components), url_(url), data_(data) +{ + OSL_ASSERT(reference != 0); +} + +void Components::WriteThread::run() { + TimeValue t = { 1, 0 }; // 1 sec + delay_.wait(&t); // must not throw; result_error is harmless and ignored + osl::MutexGuard g(lock); // must not throw + try { + try { + writeModFile(components_, url_, data_); + } catch (css::uno::RuntimeException & e) { + // Silently ignore write errors, instead of aborting: + OSL_TRACE( + "configmgr error writing modifications: %s", + rtl::OUStringToOString( + e.Message, RTL_TEXTENCODING_UTF8).getStr()); + } + } catch (...) { + reference_->clear(); + throw; + } + reference_->clear(); +} + void Components::initSingleton( css::uno::Reference< css::uno::XComponentContext > const & context) { @@ -238,7 +301,23 @@ void Components::addModification(Path const & path) { } void Components::writeModifications() { - writeModFile(*this, getModificationFileUrl(), data_); + if (!writeThread_.is()) { + writeThread_ = new WriteThread( + &writeThread_, *this, getModificationFileUrl(), data_); + writeThread_->create(); + } +} + +void Components::flushModifications() { + rtl::Reference< WriteThread > thread; + { + osl::MutexGuard g(lock); + thread = writeThread_; + } + if (thread.is()) { + thread->flush(); + thread->join(); + } } void Components::insertExtensionXcsFile( diff --git a/configmgr/source/components.hxx b/configmgr/source/components.hxx index 4fc47f791821..1c735efca6ba 100644 --- a/configmgr/source/components.hxx +++ b/configmgr/source/components.hxx @@ -94,6 +94,11 @@ public: void writeModifications(); + void flushModifications(); + // must be called with configmgr::lock unaquired; must be called before + // shutdown if writeModifications has ever been called (probably + // indirectly, via removeExtensionXcuFile) + void insertExtensionXcsFile(bool shared, rtl::OUString const & fileUri); void insertExtensionXcuFile( @@ -160,11 +165,14 @@ private: com::sun::star::beans::XPropertySet > > ExternalServices; + class WriteThread; + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > context_; Data data_; WeakRootSet roots_; ExternalServices externalServices_; + rtl::Reference< WriteThread > writeThread_; }; } diff --git a/configmgr/source/configurationprovider.cxx b/configmgr/source/configurationprovider.cxx index a89540a88158..688361a77354 100644 --- a/configmgr/source/configurationprovider.cxx +++ b/configmgr/source/configurationprovider.cxx @@ -114,6 +114,8 @@ public: private: virtual ~Service() {} + virtual void SAL_CALL disposing() { flushModifications(); } + virtual rtl::OUString SAL_CALL getImplementationName() throw (css::uno::RuntimeException) { return configuration_provider::getImplementationName(); } @@ -166,6 +168,8 @@ private: virtual css::lang::Locale SAL_CALL getLocale() throw (css::uno::RuntimeException); + void flushModifications() const; + css::uno::Reference< css::uno::XComponentContext > context_; rtl::OUString locale_; }; @@ -326,7 +330,7 @@ void Service::removeRefreshListener( } void Service::flush() throw (css::uno::RuntimeException) { - //TODO + flushModifications(); cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer( cppu::UnoType< css::util::XFlushListener >::get()); if (cont != 0) { @@ -380,6 +384,16 @@ css::lang::Locale Service::getLocale() throw (css::uno::RuntimeException) { return loc; } +void Service::flushModifications() const { + Components * components; + { + osl::MutexGuard guard(lock); + Components::initSingleton(context_); + components = &Components::getSingleton(); + } + components->flushModifications(); +} + class Factory: public cppu::WeakImplHelper1< css::lang::XSingleComponentFactory >, private boost::noncopyable -- cgit From 2cdf3404665ee5e2293bf548251b07e5785141ba Mon Sep 17 00:00:00 2001 From: sb Date: Mon, 4 Oct 2010 16:02:38 +0200 Subject: sb133: #i114705# osl::Thread::onTerminated must not be called on deleted object --- configmgr/source/components.cxx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'configmgr') diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index d1ffa8629a5f..d812e54498ac 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -175,6 +175,8 @@ private: virtual void SAL_CALL run(); + virtual void SAL_CALL onTerminated() { release(); } + rtl::Reference< WriteThread > * reference_; Components & components_; rtl::OUString url_; @@ -188,6 +190,7 @@ Components::WriteThread::WriteThread( reference_(reference), components_(components), url_(url), data_(data) { OSL_ASSERT(reference != 0); + acquire(); } void Components::WriteThread::run() { -- cgit