Commits

Anonymous committed 40f80f9 Merge

CWS-TOOLING: integrate CWS sb133

Comments (0)

Files changed (5)

configmgr/source/components.cxx

 #include "sal/config.h"
 
 #include <algorithm>
+#include <cstddef>
 #include <list>
 
 #include "com/sun/star/beans/Optional.hpp"
 #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"
 #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"
 
 }
 
+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();
+
+    virtual void SAL_CALL onTerminated() { release(); }
+
+    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);
+    acquire();
+}
+
+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)
 {
 }
 
 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(

configmgr/source/components.hxx

 
     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(
                 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_;
 };
 
 }

configmgr/source/configurationprovider.cxx

 private:
     virtual ~Service() {}
 
+    virtual void SAL_CALL disposing() { flushModifications(); }
+
     virtual rtl::OUString SAL_CALL getImplementationName()
         throw (css::uno::RuntimeException)
     { return configuration_provider::getImplementationName(); }
     virtual css::lang::Locale SAL_CALL getLocale()
         throw (css::uno::RuntimeException);
 
+    void flushModifications() const;
+
     css::uno::Reference< css::uno::XComponentContext > context_;
     rtl::OUString locale_;
 };
 }
 
 void Service::flush() throw (css::uno::RuntimeException) {
-    //TODO
+    flushModifications();
     cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
         cppu::UnoType< css::util::XFlushListener >::get());
     if (cont != 0) {
     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

desktop/inc/app.hxx

 
 		sal_Bool				InitializeInstallation( const rtl::OUString& rAppFilename );
 		sal_Bool				InitializeConfiguration();
+        void                    FlushConfiguration();
 		sal_Bool				InitializeQuickstartMode( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rSMgr );
 
 		void					HandleBootstrapPathErrors( ::utl::Bootstrap::Status, const ::rtl::OUString& aMsg );

desktop/source/app/app.cxx

         // instead of removing of the configManager just let it commit all the changes
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+        FlushConfiguration();
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
 
 	    // close splashscreen if it's still open
     {
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
+        FlushConfiguration();
         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
     }
     catch ( RuntimeException& )
     if ( bAllowRecoveryAndSessionManagement )
         bRestart = SaveTasks();
 
-    // because there is no method to flush the condiguration data, we must dispose the ConfigManager
-    Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
-    if (xCFGFlush.is())
-    {
-        xCFGFlush->flush();
-    }
-    else
-    {
-        Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
-        if (xCFGDispose.is())
-            xCFGDispose->dispose();
-    }
+    FlushConfiguration();
 
     switch( nError & EXC_MAJORTYPE )
     {
 
     // remove temp directory
     RemoveTemporaryDirectory();
+    FlushConfiguration();
     // The acceptors in the AcceptorMap must be released (in DeregisterServices)
     // with the solar mutex unlocked, to avoid deadlock:
     nAcquireCount = Application::ReleaseSolarMutex();
     return bOk;
 }
 
+void Desktop::FlushConfiguration()
+{
+    Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+    if (xCFGFlush.is())
+    {
+        xCFGFlush->flush();
+    }
+    else
+    {
+        // because there is no method to flush the condiguration data, we must dispose the ConfigManager
+        Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
+        if (xCFGDispose.is())
+            xCFGDispose->dispose();
+    }
+}
+
 sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
 {
     try