summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2016-01-28 18:31:03 -0500
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2016-01-28 18:31:03 -0500
commit62a2d525a7db09c7223a21907e1a0f4989398c15 (patch)
tree34a07512179c61d604f2ffd012fa0ae8a6be5780
parent840ad19b6409070bfb27b7644cec7cae86aa5d3c (diff)
Restoring preinit
Change-Id: I65341c57d00308d246ec90deab8050b2c4bb3e61
-rw-r--r--cppuhelper/source/defaultbootstrap.cxx17
-rw-r--r--cppuhelper/source/gcc3.map1
-rw-r--r--cppuhelper/source/servicemanager.cxx35
-rw-r--r--cppuhelper/source/servicemanager.hxx2
-rw-r--r--desktop/Library_sofficeapp.mk1
-rw-r--r--desktop/source/lib/init.cxx112
-rw-r--r--include/cppuhelper/bootstrap.hxx3
-rw-r--r--smoketest/libtest.cxx24
8 files changed, 163 insertions, 32 deletions
diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx
index 1fbbf8f541fc..b135b2c9dc89 100644
--- a/cppuhelper/source/defaultbootstrap.cxx
+++ b/cppuhelper/source/defaultbootstrap.cxx
@@ -43,6 +43,18 @@ rtl::OUString getBootstrapVariable(
return v;
}
+void default_preInitBootstrap(rtl::OUString const & aUri)
+{
+ rtl::Bootstrap bsUri(aUri);
+ if (bsUri.getHandle() == 0)
+ throw css::uno::DeploymentException("Cannot open uno ini " + aUri);
+
+ // create the service manager
+ rtl::Reference< cppuhelper::ServiceManager > aManager(new cppuhelper::ServiceManager);
+ // read rdb files
+ aManager->init(getBootstrapVariable(bsUri, "UNO_SERVICES"));
+ aManager->loadImplementations();
+}
}
css::uno::Reference< css::uno::XComponentContext >
@@ -107,4 +119,9 @@ cppu::defaultBootstrap_InitialComponentContext()
return defaultBootstrap_InitialComponentContext(getUnoIniUri());
}
+void
+cppu::preInitBootstrap()
+{
+ default_preInitBootstrap(getUnoIniUri());
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cppuhelper/source/gcc3.map b/cppuhelper/source/gcc3.map
index 12c29834ab16..3d7a5c66cdf0 100644
--- a/cppuhelper/source/gcc3.map
+++ b/cppuhelper/source/gcc3.map
@@ -423,6 +423,7 @@ global:
# enableChangeListenerNotification
_ZN4cppu19OPropertySetHelper232enableChangeListenerNotificationEh;
_ZThn*_N4cppu19OPropertySetHelper232enableChangeListenerNotificationEh;
+ _ZN4cppu16preInitBootstrapEv;
} UDK_3.7;
LIBO_UDK_3.9 { # LibO 3.7
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx
index 2140a2f74f07..ffed6baaff8c 100644
--- a/cppuhelper/source/servicemanager.cxx
+++ b/cppuhelper/source/servicemanager.cxx
@@ -42,6 +42,7 @@
#include <rtl/strbuf.hxx>
#include <sal/log.hxx>
#include <uno/environment.hxx>
+#include <osl/module.hxx>
#include "loadsharedlibcomponentfactory.hxx"
@@ -878,6 +879,40 @@ void cppuhelper::ServiceManager::loadImplementation(
}
}
+void cppuhelper::ServiceManager::loadImplementations()
+{
+ rtl::OUString aUri;
+ osl::MutexGuard g(rBHelper.rMutex);
+
+ for (Data::NamedImplementations::const_iterator iterator(
+ data_.namedImplementations.begin());
+ iterator != data_.namedImplementations.end(); ++iterator)
+ {
+ try
+ {
+ 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)
+ {
+ oslModule aModule = osl_loadModule( aUri.pData, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL );
+ SAL_INFO("lok", "loaded component library " << aUri << ( aModule ? " ok" : " no"));
+
+ // leak aModule
+ // osl_unloadModule(aModule);
+ if ( aModule )
+ iterator->second->status = Data::Implementation::STATUS_LOADED;
+ }
+ }
+}
+
void cppuhelper::ServiceManager::disposing() {
std::vector< css::uno::Reference<css::lang::XComponent> > sngls;
std::vector< css::uno::Reference< css::lang::XComponent > > comps;
diff --git a/cppuhelper/source/servicemanager.hxx b/cppuhelper/source/servicemanager.hxx
index 903084b11eef..ddf85965fda2 100644
--- a/cppuhelper/source/servicemanager.hxx
+++ b/cppuhelper/source/servicemanager.hxx
@@ -203,6 +203,8 @@ public:
css::uno::Reference< css::uno::XComponentContext > const & context,
boost::shared_ptr< Data::Implementation > & implementation);
+ void loadImplementations();
+
private:
virtual ~ServiceManager() {}
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index ed5057bab3ef..28d83f88f1d9 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -59,6 +59,7 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\
ucbhelper \
utl \
vcl \
+ xmlreader \
$(gb_UWINAPI) \
))
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index cbce5ccc9b75..8384ba44f7eb 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -53,6 +53,8 @@
#include <com/sun/star/style/XStyleFamiliesSupplier.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 <com/sun/star/util/URLTransformer.hpp>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
@@ -1681,6 +1683,7 @@ static bool initialize_uno(const OUString& aAppProgramURL)
#endif
xContext = cppu::defaultBootstrap_InitialComponentContext();
+
if (!xContext.is())
{
gImpl->maLastExceptionMsg = "XComponentContext could not be created";
@@ -1719,6 +1722,9 @@ static void lo_startmain(void*)
{
osl_setThreadName("lo_startmain");
+ if (GetpApp())
+ Application::GetSolarMutex().tryToAcquire();
+
soffice_main();
}
@@ -1747,19 +1753,38 @@ static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit:
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();
+ if (eStage != SECOND_INIT)
+ comphelper::LibreOfficeKit::setActive();
static bool bViewCallback = getenv("LOK_VIEW_CALLBACK");
comphelper::LibreOfficeKit::setViewCallback(bViewCallback);
- comphelper::LibreOfficeKit::setStatusIndicatorCallback(lo_status_indicator_callback, pLib);
+ 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;
@@ -1782,22 +1807,34 @@ 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 headless -- this is only for bitmap rendering.
+ rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
+
+ // We specifically need to make sure we have the "headless"
+ // command arg set (various code specifically checks via
+ // CommandLineArgs):
+ desktop::Desktop::GetCommandLineArgs().setHeadless();
- // 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)
+ {
+ InitVCL();
+ // pre-load all component libraries.
+ cppu::preInitBootstrap();
+ // Release Solar Mutex, lo_startmain thread should acquire it.
+ Application::ReleaseSolarMutex();
+ }
- Application::EnableHeadlessMode(true);
+ force_c_locale();
+ }
// This is horrible crack. I really would want to go back to simply just call
// InitVCL() here. The OfficeIPCThread thing is just horrible.
@@ -1818,27 +1855,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)
{
@@ -1872,6 +1916,12 @@ LibreOfficeKit *libreofficekit_hook(const char* install_path)
return libreofficekit_hook_2(install_path, NULL);
}
+SAL_JNI_EXPORT
+int lok_preinit(const char* install_path, const char* user_profile_path)
+{
+ return lo_initialize(NULL, install_path, user_profile_path);
+}
+
static void lo_destroy(LibreOfficeKit* pThis)
{
LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
diff --git a/include/cppuhelper/bootstrap.hxx b/include/cppuhelper/bootstrap.hxx
index debddcf18df2..94fa0a5fee41 100644
--- a/include/cppuhelper/bootstrap.hxx
+++ b/include/cppuhelper/bootstrap.hxx
@@ -75,6 +75,9 @@ defaultBootstrap_InitialComponentContext();
CPPUHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > SAL_CALL
defaultBootstrap_InitialComponentContext(const ::rtl::OUString & iniFile);
+CPPUHELPER_DLLPUBLIC void SAL_CALL
+preInitBootstrap();
+
/**
* An exception indicating a bootstrap error.
*
diff --git a/smoketest/libtest.cxx b/smoketest/libtest.cxx
index ae87c796112a..60ee19e62357 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" );