[Libreoffice-commits] core.git: Branch 'private/hcvcastro/preinit' - 5 commits - cppuhelper/source desktop/source vcl/source

Henry Castro hcastro at collabora.com
Sun Sep 13 16:26:57 PDT 2015


Rebased ref, commits from common ancestor:
commit 56a20f98a66aa5f81be7cdd35d1532e8655a4bd0
Author: Henry Castro <hcastro at collabora.com>
Date:   Mon Sep 7 20:27:40 2015 -0400

    cppuhelper: method 2, load implementations to invoke component factory
    
    In the preinit stage, method 2 is simplified, looping all registered
    services, and for each service load implementation is called.
    
    The disadvantages using this method, it cannot load the module with flag
    SAL_LOADMODULE_NOW set, to ensure all symbols are resolved. But we still
    can set the flag LD_BIND_NOW=1 in the parent process.
    
    Change-Id: Ieb7b90f4f43f980e15d66d490505147e166bf772

diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx
index 602fdfb..9e9aa8e 100644
--- a/cppuhelper/source/defaultbootstrap.cxx
+++ b/cppuhelper/source/defaultbootstrap.cxx
@@ -125,6 +125,6 @@ cppu::preInitBootstrap(css::uno::Reference< css::uno::XComponentContext > const
     // 1) defaultBootstrap_InitialComponentContext()
     // 2) comphelper::setProcessServiceFactory(xSFactory);
     // 3) InitVCL()
-    aService->loadImplementations();
+    aService->loadImplementations(xContext);
 }
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx
index 8be70aa..aba6745 100644
--- a/cppuhelper/source/servicemanager.cxx
+++ b/cppuhelper/source/servicemanager.cxx
@@ -881,110 +881,28 @@ void cppuhelper::ServiceManager::loadImplementation(
     }
 }
 
-void cppuhelper::ServiceManager::loadImplementations()
+void cppuhelper::ServiceManager::loadImplementations(css::uno::Reference< css::uno::XComponentContext > const & context)
 {
-    rtl::OUString aUri;
     osl::MutexGuard g(rBHelper.rMutex);
-    css::uno::Environment aSourceEnv(css::uno::Environment::getCurrent());
 
     // loop all implementations
     for (Data::NamedImplementations::const_iterator iterator(
             data_.namedImplementations.begin());
             iterator != data_.namedImplementations.end(); ++iterator)
     {
-        try
-        {
-            // expand absolute URI implementation component library
-            aUri = cppu::bootstrap_expandUri(iterator->second->info->uri);
-        }
-        catch (css::lang::IllegalArgumentException& aError)
-        {
-            throw css::uno::DeploymentException(
-                "Cannot expand URI" + iterator->second->info->uri + ": " + aError.Message,
-                static_cast< cppu::OWeakObject * >(this));
-        }
-
         if (iterator->second->info->loader == "com.sun.star.loader.SharedLibrary" &&
             iterator->second->status != Data::Implementation::STATUS_LOADED)
         {
-            // load component library
-            osl::Module aModule(aUri, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL);
-            SAL_INFO("lok", "loaded component library " << aUri << ( aModule.is() ? " ok" : " no"));
-
-            if (aModule.is() &&
-                !iterator->second->info->environment.isEmpty())
+            SAL_INFO("lok", "loading component library " +iterator->second->info->uri);
+            boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > impl = iterator->second;
+            try
             {
-                OUString aSymFactory;
-                oslGenericFunction fpFactory;
-                css::uno::Environment aTargetEnv;
-                css::uno::Reference<css::uno::XInterface> xFactory;
-
-                if(iterator->second->info->constructor.isEmpty())
-                {
-                    // expand full name component factory symbol
-                    if (iterator->second->info->prefix == "direct")
-                        aSymFactory = iterator->second->info->name.replace('.', '_') + "_" COMPONENT_GETFACTORY;
-                    else if (!iterator->second->info->prefix.isEmpty())
-                        aSymFactory = iterator->second->info->prefix + "_" COMPONENT_GETFACTORY;
-                    else
-                        aSymFactory = COMPONENT_GETFACTORY;
-
-                    // get function symbol component factory
-                    fpFactory = aModule.getFunctionSymbol(aSymFactory);
-                    if (fpFactory == 0)
-                    {
-                        throw css::loader::CannotActivateFactoryException(
-                            ("no factory symbol \"" + aSymFactory + "\" in component library :" + aUri),
-                            css::uno::Reference<css::uno::XInterface>());
-                    }
-
-                    aTargetEnv = cppuhelper::detail::getEnvironment(iterator->second->info->environment, iterator->second->info->name);
-                    component_getFactoryFunc fpComponentFactory = reinterpret_cast<component_getFactoryFunc>(fpFactory);
-
-                    if (aSourceEnv.get() == aTargetEnv.get())
-                    {
-                        // invoke function component factory
-                        OString aImpl(rtl::OUStringToOString(iterator->second->info->name, RTL_TEXTENCODING_ASCII_US));
-                        xFactory.set(css::uno::Reference<css::uno::XInterface>(static_cast<css::uno::XInterface *>(
-                            (*fpComponentFactory)(aImpl.getStr(), this, 0)), SAL_NO_ACQUIRE));
-                    }
-                }
-                else
-                {
-                    // get function symbol component factory
-                    fpFactory = aModule.getFunctionSymbol(iterator->second->info->constructor);
-                }
-
-                css::uno::Reference<css::lang::XSingleComponentFactory> xSCFactory;
-                css::uno::Reference<css::lang::XSingleServiceFactory> xSSFactory;
-
-                // query interface XSingleComponentFactory or XSingleServiceFactory
-                if (xFactory.is())
-                {
-                    xSCFactory.set(xFactory, css::uno::UNO_QUERY);
-                    if (!xSCFactory.is())
-                    {
-                        xSSFactory.set(xFactory, css::uno::UNO_QUERY);
-                        if (!xSSFactory.is())
-                        {
-                            throw css::uno::DeploymentException(
-                                ("Implementation " + iterator->second->info->name
-                                  + " does not provide a constructor or factory"),
-                                static_cast< cppu::OWeakObject * >(this));
-                        }
-                    }
-                }
-
-                if (!iterator->second->info->constructor.isEmpty() && fpFactory)
-                    iterator->second->constructor = reinterpret_cast<ImplementationConstructorFn *>(fpFactory);
-
-                iterator->second->factory1 = xSCFactory;
-                iterator->second->factory2 = xSSFactory;
-                iterator->second->status = Data::Implementation::STATUS_LOADED;
-
+                loadImplementation(context, impl);
+            }
+            catch (css::uno::RuntimeException & aError)
+            {
+                SAL_WARN("lok", aError.Message);
             }
-            // leak aModule
-            aModule.release();
         }
     }
 }
diff --git a/cppuhelper/source/servicemanager.hxx b/cppuhelper/source/servicemanager.hxx
index ddf85965f..571f857 100644
--- a/cppuhelper/source/servicemanager.hxx
+++ b/cppuhelper/source/servicemanager.hxx
@@ -203,7 +203,7 @@ public:
         css::uno::Reference< css::uno::XComponentContext > const & context,
         boost::shared_ptr< Data::Implementation > & implementation);
 
-    void loadImplementations();
+    void loadImplementations(css::uno::Reference< css::uno::XComponentContext > const & context);
 
 private:
     virtual ~ServiceManager() {}
commit c22ddbf7ca5b1c94dedb87ea4e93b25415fc64e1
Author: Henry Castro <hcastro at collabora.com>
Date:   Sat Sep 12 12:11:43 2015 -0400

    vcl: desktop terminate, to dispose objects
    
    In the preinit stage, the Desktop terminate() method is never called
    when lo_startmain thread is disposing objects. This produces debug
    assertions and osl assertions.
    
    It is forced to call terminate() method, when a tiled rendering case is
    active then it has a clean disposing objects process.
    
    However DBGGUI_DEINIT_SOLARMUTEXCHECK() check is moved at the end to
    prevent debug assertions solar mutex complains.
    
    Change-Id: I4a9b6398296d9150ab748a8d48868a08e7232909

diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index fcc7b8c..ce95437 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -28,6 +28,7 @@
 #include "tools/resmgr.hxx"
 
 #include "comphelper/processfactory.hxx"
+#include "comphelper/lok.hxx"
 
 #include "unotools/syslocaleoptions.hxx"
 #include "vcl/svapp.hxx"
@@ -445,8 +446,6 @@ void DeInitVCL()
     }
     pSVData->mpDefaultWin.disposeAndClear();
 
-    DBGGUI_DEINIT_SOLARMUTEXCHECK();
-
     if ( pSVData->mpUnoWrapper )
     {
         try
@@ -454,6 +453,12 @@ void DeInitVCL()
             uno::Reference<frame::XDesktop2> const xDesktop = frame::Desktop::create(
                     comphelper::getProcessComponentContext() );
             xDesktop->addEventListener(new VCLUnoWrapperDeleter());
+
+            if (comphelper::LibreOfficeKit::isActive())
+            {
+                SAL_WARN_IF(!xDesktop.is(), "desktop.app", "No Desktop interface");
+                xDesktop->terminate();
+            }
         }
         catch (uno::Exception const&)
         {
@@ -567,6 +572,8 @@ void DeInitVCL()
     }
 
     EmbeddedFontsHelper::clearTemporaryFontFiles();
+
+    DBGGUI_DEINIT_SOLARMUTEXCHECK();
 }
 
 // only one call is allowed
commit 09dcaeffd54155913d79ca240a0033c83ae017dc
Author: Henry Castro <hcastro at collabora.com>
Date:   Mon Sep 7 17:43:04 2015 -0400

    vcl: assign NULL after deleting
    
    In the preinit stage, the VCL initialization is done by the parent process
    and when the lo_startmain thread de-initialize the VCL, some services are
    disposed early, and it causes segmentation violation.
    
    So it is ensured that pointers to service objetcs is set NULL after the
    delete.
    
    Change-Id: I65ecfc2d2694a981ec2986988efabdfd28d0cce4

diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index 14cf94d..94c23db 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -102,10 +102,10 @@ void ImplDeInitSVData()
 
     // delete global instance data
     if( pSVData->mpSettingsConfigItem )
-        delete pSVData->mpSettingsConfigItem;
+        delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL;
 
     if( pSVData->mpDockingManager )
-        delete pSVData->mpDockingManager;
+        delete pSVData->mpDockingManager, pSVData->mpDockingManager = NULL;
 
     if( pSVData->maCtrlData.mpFieldUnitStrings )
         delete pSVData->maCtrlData.mpFieldUnitStrings, pSVData->maCtrlData.mpFieldUnitStrings = NULL;
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index df187484..fcc7b8c 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -390,7 +390,7 @@ void DeInitVCL()
         delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL;
 
     if ( pSVData->maAppData.mpIdleMgr )
-        delete pSVData->maAppData.mpIdleMgr;
+        delete pSVData->maAppData.mpIdleMgr, pSVData->maAppData.mpIdleMgr = NULL;
     Scheduler::ImplDeInitScheduler();
 
     if ( pSVData->maWinData.mpMsgBoxImgList )
@@ -554,7 +554,11 @@ void DeInitVCL()
     pSVData->mpSalTimer = NULL;
 
     // Deinit Sal
-    DestroySalInstance( pSVData->mpDefInst );
+    if (pSVData->mpDefInst)
+    {
+        DestroySalInstance( pSVData->mpDefInst );
+        pSVData->mpDefInst = NULL;
+    }
 
     if( pOwnSvApp )
     {
commit 3941ed18e1836ad51aa36caa70dbcca2325b5e4c
Author: Henry Castro <hcastro at collabora.com>
Date:   Mon Sep 7 17:33:09 2015 -0400

    vcl: add isInitVCL, to not initialize twice
    
    In the preinit stage, the VCL is initialized in the parent process
    and when the lo_startmain thread is started, the thread initialize
    VCL again.
    
    It is not necessary to initialize twice.
    
    Change-Id: I819cf0125afe7760c3f4d91c420d36a3a383902c

diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index b24714d..df187484 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -91,6 +91,8 @@
 
 using namespace ::com::sun::star;
 
+bool isInitVCL();
+
 oslSignalAction SAL_CALL VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo* pInfo)
 {
     static bool bIn = false;
@@ -160,7 +162,7 @@ int ImplSVMain()
 
     int nReturn = EXIT_FAILURE;
 
-    bool bInit = InitVCL();
+    bool bInit = (!isInitVCL() ? InitVCL() : true);
 
     if( bInit )
     {
@@ -243,6 +245,14 @@ uno::Any SAL_CALL DesktopEnvironmentContext::getValueByName( const OUString& Nam
     return retVal;
 }
 
+bool isInitVCL()
+{
+    ImplSVData* pSVData = ImplGetSVData();
+    return  pExceptionHandler != NULL &&
+            pSVData->mpApp != NULL &&
+            pSVData->mpDefInst != NULL;
+}
+
 bool InitVCL()
 {
     if( pExceptionHandler != NULL )
commit 69f6f8bd63afde4098aca77cbfbedb1a46601ba3
Author: Henry Castro <hcastro at collabora.com>
Date:   Mon Sep 7 17:21:38 2015 -0400

    desktop: add InitVCL to lo_initialize
    
    In the preinit stage, VCL initialization is required before call
    preInitBootstrap that load implementations.
    
    However, InitVCL acquire the Solar Mutex, and it is released because
    it will produce deadlock between the parent process and lo_startmain
    thread.
    
    On the other hand, lo_startmain thread acquires the Solar Mutex, if
    not debug assertion complains.
    
    Change-Id: Ib5d4b5788441b92a30f58a129441ffeba076c181

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 9e1f1b4..e02d2d1 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -894,7 +894,7 @@ static void aBasicErrorFunc(const OUString& rError, const OUString& rAction)
     fprintf(stderr, "Unexpected basic error dialog '%s'\n", aBuffer.getStr());
 }
 
-static bool initialize_uno(const OUString& aAppProgramURL, bool bPreInit)
+static bool initialize_uno(const OUString& aAppProgramURL)
 {
 #ifdef IOS
     // For iOS we already hardocde the inifile as "rc" in the .app directory.
@@ -903,14 +903,8 @@ static bool initialize_uno(const OUString& aAppProgramURL, bool bPreInit)
     rtl::Bootstrap::setIniFilename(aAppProgramURL + "/" SAL_CONFIGFILE("soffice"));
 #endif
 
-    if (bPreInit)
-    {
-        // pre-load all component libraries.
-        cppu::preInitBootstrap();
-        return true;
-    }
-
     xContext = cppu::defaultBootstrap_InitialComponentContext();
+
     if (!xContext.is())
     {
         gImpl->maLastExceptionMsg = "XComponentContext could not be created";
@@ -947,6 +941,11 @@ static bool initialize_uno(const OUString& aAppProgramURL, bool bPreInit)
 
 static void lo_startmain(void*)
 {
+    osl_setThreadName("lo_startmain");
+
+    if (GetpApp())
+        Application::GetSolarMutex().tryToAcquire();
+
     soffice_main();
 }
 
@@ -973,11 +972,6 @@ static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit:
     }
 }
 
-/// pre-load and parse all filter XML
-static void forceLoadFilterXML()
-{
-}
-
 static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char* pUserProfilePath)
 {
     enum {
@@ -1034,12 +1028,9 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
         {
             SAL_INFO("lok", "Attempting to initalize UNO");
 
-            if (!initialize_uno(aAppURL, (eStage == PRE_INIT)))
+            if (!initialize_uno(aAppURL))
                 return false;
 
-            if (eStage != PRE_INIT)
-                force_c_locale();
-
             // Force headless -- this is only for bitmap rendering.
             rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
 
@@ -1049,11 +1040,17 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
             desktop::Desktop::GetCommandLineArgs().setHeadless();
 
             Application::EnableHeadlessMode(true);
-        }
 
-        if (eStage == PRE_INIT)
-        {
-            forceLoadFilterXML();
+            if (eStage == PRE_INIT)
+            {
+                InitVCL();
+                // pre-load all component libraries.
+                cppu::preInitBootstrap(xContext);
+                // Release Solar Mutex, lo_startmain thread should acquire it.
+                Application::ReleaseSolarMutex();
+            }
+
+            force_c_locale();
         }
 
         // This is horrible crack. I really would want to go back to simply just call


More information about the Libreoffice-commits mailing list