[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