diff options
-rw-r--r-- | cppuhelper/source/defaultbootstrap.cxx | 16 | ||||
-rw-r--r-- | cppuhelper/source/gcc3.map | 5 | ||||
-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 | 113 | ||||
-rw-r--r-- | include/cppuhelper/detail/preinit.hxx | 29 | ||||
-rw-r--r-- | smoketest/libtest.cxx | 24 |
8 files changed, 193 insertions, 32 deletions
diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx index bede6b518af0..c0a2c2edc6f7 100644 --- a/cppuhelper/source/defaultbootstrap.cxx +++ b/cppuhelper/source/defaultbootstrap.cxx @@ -18,6 +18,7 @@ #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/lang/XSingleComponentFactory.hpp> #include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/detail/preinit.hxx> #include <cppuhelper/component_context.hxx> #include <rtl/bootstrap.hxx> #include <rtl/ref.hxx> @@ -107,4 +108,19 @@ cppu::defaultBootstrap_InitialComponentContext() return defaultBootstrap_InitialComponentContext(getUnoIniUri()); } +void +cppu::preInitBootstrap() +{ + rtl::OUString iniUri(getUnoIniUri()); + rtl::Bootstrap bs(iniUri); + if (bs.getHandle() == nullptr) + throw css::uno::DeploymentException("Cannot open uno ini " + iniUri); + + // create the service manager + rtl::Reference< cppuhelper::ServiceManager > aManager(new cppuhelper::ServiceManager); + // read rdb files + aManager->init(getBootstrapVariable(bs, "UNO_SERVICES")); + aManager->loadAllImplementations(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cppuhelper/source/gcc3.map b/cppuhelper/source/gcc3.map index 12c29834ab16..20d0e137eef6 100644 --- a/cppuhelper/source/gcc3.map +++ b/cppuhelper/source/gcc3.map @@ -436,3 +436,8 @@ GLIBCXX_3.4 { _ZGVNSt7num_put*; _ZNSt7num_put*; _ZNSs4_Rep20_S_empty_rep_storageE; }; + +PRIVATE_1.0 { # LibO 5.2 + global: + _ZN4cppu16preInitBootstrapEv; +}; diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx index 2d824d4aaa3f..d89289a165a4 100644 --- a/cppuhelper/source/servicemanager.cxx +++ b/cppuhelper/source/servicemanager.cxx @@ -34,6 +34,7 @@ #include <cppuhelper/implbase3.hxx> #include <cppuhelper/supportsservice.hxx> #include <osl/file.hxx> +#include <osl/module.hxx> #include <rtl/ref.hxx> #include <rtl/uri.hxx> #include <rtl/ustring.hxx> @@ -875,6 +876,40 @@ void cppuhelper::ServiceManager::loadImplementation( } } +void cppuhelper::ServiceManager::loadAllImplementations() +{ + 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 c217cbce39f5..7e8f4e66e7e6 100644 --- a/cppuhelper/source/servicemanager.hxx +++ b/cppuhelper/source/servicemanager.hxx @@ -203,6 +203,8 @@ public: css::uno::Reference< css::uno::XComponentContext > const & context, std::shared_ptr< Data::Implementation > & implementation); + void loadAllImplementations(); + private: virtual ~ServiceManager(); diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk index 9be7c2dcb3bb..d7b6dbac4b2f 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 f73a97658bfc..f24ecd2553ad 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -28,6 +28,7 @@ #include <rtl/strbuf.hxx> #include <rtl/uri.hxx> #include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/detail/preinit.hxx> #include <comphelper/dispatchcommand.hxx> #include <comphelper/lok.hxx> #include <comphelper/processfactory.hxx> @@ -47,6 +48,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> #include <com/sun/star/text/TextContentAnchorType.hpp> @@ -1772,6 +1775,7 @@ static bool initialize_uno(const OUString& aAppProgramURL) #endif xContext = cppu::defaultBootstrap_InitialComponentContext(); + if (!xContext.is()) { gImpl->maLastExceptionMsg = "XComponentContext could not be created"; @@ -1804,6 +1808,9 @@ static void lo_startmain(void*) { osl_setThreadName("lo_startmain"); + if (GetpApp()) + Application::GetSolarMutex().tryToAcquire(); + soffice_main(); } @@ -1832,19 +1839,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("UserInstallation", OUString(pUserProfilePath, strlen(pUserProfilePath), RTL_TEXTENCODING_UTF8)); OUString aAppPath; @@ -1867,22 +1893,34 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char try { - SAL_INFO("lok", "Attempting to initialize UNO"); - if (!initialize_uno(aAppURL)) + if (eStage != SECOND_INIT) { - return false; - } - force_c_locale(); + SAL_INFO("lok", "Attempting to initialize UNO"); + + if (!initialize_uno(aAppURL)) + return false; - // Force headless -- this is only for bitmap rendering. - rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp"); + // 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); + 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(); + } + + 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. @@ -1903,27 +1941,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, nullptr); - 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, nullptr); + 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) { @@ -1971,6 +2016,12 @@ LibreOfficeKit *libreofficekit_hook(const char* install_path) return libreofficekit_hook_2(install_path, nullptr); } +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/detail/preinit.hxx b/include/cppuhelper/detail/preinit.hxx new file mode 100644 index 000000000000..b21929aa58d8 --- /dev/null +++ b/include/cppuhelper/detail/preinit.hxx @@ -0,0 +1,29 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_CPPUHELPER_DETAIL_PREINIT_HXX +#define INCLUDED_CPPUHELPER_DETAIL_PREINIT_HXX + +#include <cppuhelper/cppuhelperdllapi.h> + +namespace cppu +{ + +#if defined LIBO_INTERNAL_ONLY + +CPPUHELPER_DLLPUBLIC void SAL_CALL +preInitBootstrap(); + +#endif // LIBO_INTERNAL_ONLY + +} // namespace cppu + +#endif // INCLUDED_CPPUHELPER_DETAIL_PREINIT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/smoketest/libtest.cxx b/smoketest/libtest.cxx index 29959b07654d..98607fbd9609 100644 --- a/smoketest/libtest.cxx +++ b/smoketest/libtest.cxx @@ -82,7 +82,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" ); |