diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2016-01-28 18:31:03 -0500 |
---|---|---|
committer | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2016-01-28 18:31:03 -0500 |
commit | 62a2d525a7db09c7223a21907e1a0f4989398c15 (patch) | |
tree | 34a07512179c61d604f2ffd012fa0ae8a6be5780 | |
parent | 840ad19b6409070bfb27b7644cec7cae86aa5d3c (diff) |
Restoring preinit
Change-Id: I65341c57d00308d246ec90deab8050b2c4bb3e61
-rw-r--r-- | cppuhelper/source/defaultbootstrap.cxx | 17 | ||||
-rw-r--r-- | cppuhelper/source/gcc3.map | 1 | ||||
-rw-r--r-- | cppuhelper/source/servicemanager.cxx | 35 | ||||
-rw-r--r-- | cppuhelper/source/servicemanager.hxx | 2 | ||||
-rw-r--r-- | desktop/Library_sofficeapp.mk | 1 | ||||
-rw-r--r-- | desktop/source/lib/init.cxx | 112 | ||||
-rw-r--r-- | include/cppuhelper/bootstrap.hxx | 3 | ||||
-rw-r--r-- | smoketest/libtest.cxx | 24 |
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" ); |