[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.0' - 2 commits - desktop/source include/LibreOfficeKit smoketest/libtest.cxx

Michael Meeks michael.meeks at collabora.com
Tue Aug 18 04:00:45 PDT 2015


 desktop/source/lib/init.cxx                 |  135 +++++++++++++++++++++-------
 include/LibreOfficeKit/LibreOfficeKitInit.h |   60 +++++++-----
 smoketest/libtest.cxx                       |   24 ++++
 3 files changed, 162 insertions(+), 57 deletions(-)

New commits:
commit a320a722439c14b7e6de88fd029e5236032cbda6
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Aug 18 12:10:05 2015 +0100

    Stub initial pre-init phase.
    
    Change-Id: I92d172a166606189ce386826eee566623ec4a83c

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 88a2f06..a435b7ef 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -42,6 +42,8 @@
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/ucb/XContentProvider.hpp>
 #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
 
 #include <vcl/svapp.hxx>
 #include <vcl/svpforlokit.hxx>
@@ -964,17 +966,69 @@ static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit:
     }
 }
 
+/// pre-load all C++ component factories and leak references to them.
+static void forceLoadAllNativeComponents()
+{
+    // FIXME: we need to inject RTLD_NOW into here, either by a
+    // putenv("LD_BIND_NOW=1") in parent process or ... (?).
+
+    try {
+        uno::Reference<container::XContentEnumerationAccess> xEnumAcc(
+            xContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
+        uno::Reference<container::XHierarchicalNameAccess> xTypeMgr(
+            xContext->getValueByName(
+                "/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
+            css::uno::UNO_QUERY_THROW);
+        uno::Sequence<OUString> aServiceNames(
+            xContext->getServiceManager()->getAvailableServiceNames());
+
+        for (sal_Int32 i = 0; i != aServiceNames.getLength(); ++i)
+        {
+            css::uno::Reference<css::container::XEnumeration> xServiceImpls(
+                xEnumAcc->createContentEnumeration(aServiceNames[i]),
+                css::uno::UNO_SET_THROW);
+            SAL_INFO("lok", "service " << aServiceNames[i]);
+            // FIXME: need to actually load and link each native DSO.
+        }
+    } catch (const uno::Exception &) {
+    }
+}
+
+/// pre-load and parse all filter XML
+static void forceLoadFilterXML()
+{
+}
+
 static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char* pUserProfilePath)
 {
+    enum {
+        PRE_INIT,     // setup shared data in master process
+        SECOND_INIT,  // complete init. after fork
+        FULL_INIT     // do a standard complete init.
+    } eStage;
+
+    // Did we do a pre-initialize
+    static bool bPreInited = false;
+
+    // What stage are we at ?
+    if (pThis == NULL)
+        eStage = PRE_INIT;
+    else if (bPreInited)
+        eStage = SECOND_INIT;
+    else
+        eStage = FULL_INIT;
+
     LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
 
     if (bInitialized)
         return 1;
 
-    comphelper::LibreOfficeKit::setActive();
-    comphelper::LibreOfficeKit::setStatusIndicatorCallback(lo_status_indicator_callback, pLib);
+    if (eStage != SECOND_INIT)
+        comphelper::LibreOfficeKit::setActive();
+    if (eStage != PRE_INIT)
+        comphelper::LibreOfficeKit::setStatusIndicatorCallback(lo_status_indicator_callback, pLib);
 
-    if (pUserProfilePath)
+    if (eStage != SECOND_INIT && pUserProfilePath)
         rtl::Bootstrap::set(OUString("UserInstallation"), OUString(pUserProfilePath, strlen(pUserProfilePath), RTL_TEXTENCODING_UTF8));
 
     OUString aAppPath;
@@ -997,22 +1051,30 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
 
     try
     {
-        SAL_INFO("lok", "Attempting to initalize UNO");
-        if (!initialize_uno(aAppURL))
+        if (eStage != SECOND_INIT)
         {
-            return false;
-        }
-        force_c_locale();
+            SAL_INFO("lok", "Attempting to initalize UNO");
 
-        // Force headless -- this is only for bitmap rendering.
-        rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
+            if (!initialize_uno(aAppURL))
+                return false;
+            force_c_locale();
 
-        // We specifically need to make sure we have the "headless"
-        // command arg set (various code specifically checks via
-        // CommandLineArgs):
-        desktop::Desktop::GetCommandLineArgs().setHeadless();
+            // Force headless -- this is only for bitmap rendering.
+            rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
 
-        Application::EnableHeadlessMode(true);
+            // We specifically need to make sure we have the "headless"
+            // command arg set (various code specifically checks via
+            // CommandLineArgs):
+            desktop::Desktop::GetCommandLineArgs().setHeadless();
+
+            Application::EnableHeadlessMode(true);
+        }
+
+        if (eStage == PRE_INIT)
+        {
+            forceLoadAllNativeComponents();
+            forceLoadFilterXML();
+        }
 
         // This is horrible crack. I really would want to go back to simply just call
         // InitVCL() here. The OfficeIPCThread thing is just horrible.
@@ -1033,27 +1095,34 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
         // the Thread from wherever (it's done again in Desktop::Main), and can
         // then use it to wait until we're definitely ready to continue.
 
-        SAL_INFO("lok", "Enabling OfficeIPCThread");
-        OfficeIPCThread::EnableOfficeIPCThread();
-        SAL_INFO("lok", "Starting soffice_main");
-        pLib->maThread = osl_createThread(lo_startmain, NULL);
-        SAL_INFO("lok", "Waiting for OfficeIPCThread");
-        OfficeIPCThread::WaitForReady();
-        SAL_INFO("lok", "OfficeIPCThread ready -- continuing");
-
-        // If the Thread has been disabled again that indicates that a
-        // restart is required (or in any case we don't have a useable
-        // process around).
-        if (!OfficeIPCThread::IsEnabled())
+        if (eStage != PRE_INIT)
         {
-            fprintf(stderr, "LOK init failed -- restart required\n");
-            return false;
+            SAL_INFO("lok", "Enabling OfficeIPCThread");
+            OfficeIPCThread::EnableOfficeIPCThread();
+            SAL_INFO("lok", "Starting soffice_main");
+            pLib->maThread = osl_createThread(lo_startmain, NULL);
+            SAL_INFO("lok", "Waiting for OfficeIPCThread");
+            OfficeIPCThread::WaitForReady();
+            SAL_INFO("lok", "OfficeIPCThread ready -- continuing");
+
+            // If the Thread has been disabled again that indicates that a
+            // restart is required (or in any case we don't have a useable
+            // process around).
+            if (!OfficeIPCThread::IsEnabled())
+            {
+                fprintf(stderr, "LOK init failed -- restart required\n");
+                return false;
+            }
         }
 
-        ErrorHandler::RegisterDisplay(aBasicErrorFunc);
+        if (eStage != SECOND_INIT)
+            ErrorHandler::RegisterDisplay(aBasicErrorFunc);
 
         SAL_INFO("lok", "LOK Initialized");
-        bInitialized = true;
+        if (eStage == PRE_INIT)
+            bPreInited = true;
+        else
+            bInitialized = true;
     }
     catch (css::uno::Exception& exception)
     {
@@ -1088,10 +1157,10 @@ LibreOfficeKit *libreofficekit_hook(const char* install_path)
 }
 
 SAL_JNI_EXPORT
-int lok_preinit()
+int lok_preinit(const char* install_path, const char* user_profile_path)
 {
     SAL_INFO("lok", "Hello World");
-    return 0;
+    return lo_initialize(NULL, install_path, user_profile_path);
 }
 
 static void lo_destroy(LibreOfficeKit* pThis)
diff --git a/smoketest/libtest.cxx b/smoketest/libtest.cxx
index ae87c79..60ee19e 100644
--- a/smoketest/libtest.cxx
+++ b/smoketest/libtest.cxx
@@ -83,7 +83,29 @@ int main (int argc, char **argv)
         return 1;
 
     // coverity[tainted_string] - build time test tool
-    Office *pOffice = lok_cpp_init( argv[1] );
+    char *install_path = argv[1];
+
+    if( argc > 4 )
+    {
+        fprintf( stderr, "testing preinit\n");
+        char *imp_lib;
+        void *dlhandle;
+        dlhandle = lok_dlopen( install_path, &imp_lib );
+        if( !dlhandle )
+        {
+            fprintf( stderr, "Failed to link '%s'\n", lok_dlerror() );
+            return -1;
+        }
+        LokHookPreInit *preinit = (LokHookPreInit *) lok_dlsym( dlhandle, "lok_preinit" );
+        if( !preinit )
+        {
+            fprintf( stderr, "Failed to find pre-init symbol: %s\n", lok_dlerror() );
+            return -1;
+        }
+        preinit( install_path, NULL );
+    }
+
+    Office *pOffice = lok_cpp_init( install_path );
     if( !pOffice )
     {
         fprintf( stderr, "Failed to initialize\n" );
commit c35958c5cc8bf637c4911b1251e695234f761a0b
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Aug 18 12:09:08 2015 +0100

    lok: namespace and re-work various types & helper functions.
    
    Change-Id: I36e2a01822883251f9556fcde0e0a9830356ac98

diff --git a/include/LibreOfficeKit/LibreOfficeKitInit.h b/include/LibreOfficeKit/LibreOfficeKitInit.h
index f1966c7..c2f3426 100644
--- a/include/LibreOfficeKit/LibreOfficeKitInit.h
+++ b/include/LibreOfficeKit/LibreOfficeKitInit.h
@@ -40,7 +40,7 @@ extern "C"
     #endif
     #define SEPARATOR         '/'
 
-    void *_dlopen(const char *pFN)
+    void *lok_loadlib(const char *pFN)
     {
         return dlopen(pFN, RTLD_LAZY
 #if defined __clang__ && defined __linux__ \
@@ -52,17 +52,17 @@ extern "C"
                       );
     }
 
-    char *_dlerror(void)
+    char *lok_dlerror(void)
     {
         return dlerror();
     }
 
-    void *_dlsym(void *Hnd, const char *pName)
+    void *lok_dlsym(void *Hnd, const char *pName)
     {
         return dlsym(Hnd, pName);
     }
 
-    int _dlclose(void *Hnd)
+    int lok_dlclose(void *Hnd)
     {
         return dlclose(Hnd);
     }
@@ -80,24 +80,24 @@ extern "C"
     #define SEPARATOR         '\\'
     #define UNOPATH           "\\..\\URE\\bin"
 
-    void *_dlopen(const char *pFN)
+    void *lok_loadlib(const char *pFN)
     {
         return (void *) LoadLibrary(pFN);
     }
 
-    char *_dlerror(void)
+    char *lok_dlerror(void)
     {
         LPSTR buf = NULL;
         FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, reinterpret_cast<LPSTR>(&buf), 0, NULL);
         return buf;
     }
 
-    void *_dlsym(void *Hnd, const char *pName)
+    void *lok_dlsym(void *Hnd, const char *pName)
     {
         return GetProcAddress((HINSTANCE) Hnd, pName);
     }
 
-    int _dlclose(void *Hnd)
+    int lok_dlclose(void *Hnd)
     {
         return FreeLibrary((HINSTANCE) Hnd);
     }
@@ -139,16 +139,12 @@ extern "C"
     }
 #endif
 
-typedef LibreOfficeKit *(HookFunction)( const char *install_path);
-
-typedef LibreOfficeKit *(HookFunction2)( const char *install_path, const char *user_profile_path );
-
-static LibreOfficeKit *lok_init_2( const char *install_path,  const char *user_profile_path )
+static void *lok_dlopen( const char *install_path, char ** _imp_lib )
 {
     char *imp_lib;
     void *dlhandle;
-    HookFunction *pSym;
-    HookFunction2 *pSym2;
+
+    *_imp_lib = NULL;
 
 #if !(defined(__APPLE__) && defined(__arm__))
     size_t partial_length;
@@ -172,7 +168,7 @@ static LibreOfficeKit *lok_init_2( const char *install_path,  const char *user_p
     imp_lib[partial_length++] = SEPARATOR;
     strcpy(imp_lib + partial_length, TARGET_LIB);
 
-    dlhandle = _dlopen(imp_lib);
+    dlhandle = lok_loadlib(imp_lib);
     if (!dlhandle)
     {
         // If TARGET_LIB exists, and likely is a real library (not a
@@ -183,18 +179,18 @@ static LibreOfficeKit *lok_init_2( const char *install_path,  const char *user_p
         if (stat(imp_lib, &st) == 0 && st.st_size > 100)
         {
             fprintf(stderr, "failed to open library '%s': %s\n",
-                    imp_lib, _dlerror());
+                    imp_lib, lok_dlerror());
             free(imp_lib);
             return NULL;
         }
 
         strcpy(imp_lib + partial_length, TARGET_MERGED_LIB);
 
-        dlhandle = _dlopen(imp_lib);
+        dlhandle = lok_loadlib(imp_lib);
         if (!dlhandle)
         {
             fprintf(stderr, "failed to open library '%s': %s\n",
-                    imp_lib, _dlerror());
+                    imp_lib, lok_dlerror());
             free(imp_lib);
             return NULL;
         }
@@ -203,23 +199,41 @@ static LibreOfficeKit *lok_init_2( const char *install_path,  const char *user_p
     imp_lib = strdup("the app executable");
     dlhandle = RTLD_MAIN_ONLY;
 #endif
+    *_imp_lib = imp_lib;
+    return dlhandle;
+}
+
+typedef LibreOfficeKit *(LokHookFunction)( const char *install_path);
+
+typedef LibreOfficeKit *(LokHookFunction2)( const char *install_path, const char *user_profile_path );
+
+typedef int             (LokHookPreInit)  ( const char *install_path, const char *user_profile_path );
+
+static LibreOfficeKit *lok_init_2( const char *install_path,  const char *user_profile_path )
+{
+    char *imp_lib;
+    void *dlhandle;
+    LokHookFunction *pSym;
+    LokHookFunction2 *pSym2;
+
+    dlhandle = lok_dlopen(install_path, &imp_lib);
 
-    pSym2 = (HookFunction2 *) _dlsym( dlhandle, "libreofficekit_hook_2" );
+    pSym2 = (LokHookFunction2 *) lok_dlsym(dlhandle, "libreofficekit_hook_2");
     if (!pSym2)
     {
         if (user_profile_path != NULL)
         {
             fprintf( stderr, "the LibreOffice version in '%s' does not support passing a user profile to the hook function\n",
                      imp_lib );
-            _dlclose( dlhandle );
+            lok_dlclose( dlhandle );
             free( imp_lib );
             return NULL;
         }
-        pSym = (HookFunction *) _dlsym( dlhandle, "libreofficekit_hook" );
+        pSym = (LokHookFunction *) lok_dlsym( dlhandle, "libreofficekit_hook" );
         if (!pSym)
         {
             fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib );
-            _dlclose( dlhandle );
+            lok_dlclose( dlhandle );
             free( imp_lib );
             return NULL;
         }


More information about the Libreoffice-commits mailing list