cppuhelper/source/defaultbootstrap.cxx | 22 ++++++ cppuhelper/source/gcc3.map | 1 cppuhelper/source/servicemanager.cxx | 111 ++++++++++++++++++++++++++++++++ cppuhelper/source/servicemanager.hxx | 2 desktop/Library_sofficeapp.mk | 1 desktop/source/lib/init.cxx | 112 +++++++++++++++++++++++---------- include/cppuhelper/bootstrap.hxx | 14 ++++ smoketest/libtest.cxx | 24 ++++++- vcl/headless/svpframe.cxx | 6 + vcl/source/app/svdata.cxx | 4 - vcl/source/app/svmain.cxx | 31 +++++++-- vcl/source/window/window.cxx | 4 + 12 files changed, 292 insertions(+), 40 deletions(-)
New commits: commit 55c467f23c00805e89ba72f941ca08e575bd7d43 Author: Michael Meeks <[email protected]> Date: Fri Jan 29 15:31:58 2016 +0100 headless: don't let windows become really visible to avoid paints. Paint at the wrong time has a habit of allocating over-large OutputDevice's for the drawing layer; saves 7Mb of heap for a dummy tilebench document. Change-Id: Ie06df705a55faadea2b06fd24b904d95ae64fd83 (cherry picked from commit 5f1529cc95dcebf7066765f525d1e61776bfecda) diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index d8c7846..1e4e875 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -1349,6 +1349,10 @@ SalGraphics* Window::ImplGetFrameGraphics() const void Window::ImplSetReallyVisible() { + // For now, no window is really visible in headless mode. + if( Application::IsHeadlessModeEnabled() ) + return; + // #i43594# it is possible that INITSHOW was never send, because the visibility state changed between // ImplCallInitShow() and ImplSetReallyVisible() when called from Show() // mbReallyShown is a useful indicator commit 4e195870ec16086ef31a51f65af0d7cbfeea723d Author: Michael Meeks <[email protected]> Date: Fri Jan 29 15:11:48 2016 +0100 headless: for now don't allocate big cairo surfaces for invisible frames. This was ~10Mb of RAM for a hello-world.odt under tile-bench. Change-Id: Ie0787676be754ac81eb8ec036c9757a1bb2f2220 (cherry picked from commit edaccf928c4e4e90a024e766aecd07181e29fd97) diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx index e1218d7..56e9dd9 100644 --- a/vcl/headless/svpframe.cxx +++ b/vcl/headless/svpframe.cxx @@ -292,10 +292,16 @@ void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u aFrameSize.setX( 1 ); if( aFrameSize.getY() == 0 ) aFrameSize.setY( 1 ); + + // Creating backing surfaces for invisible windows costs a big chunk of RAM. + if (Application::IsHeadlessModeEnabled()) + aFrameSize = B2IVector( 1, 1 ); + sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(m_nScanlineFormat, aFrameSize.getX()); m_aFrame = createBitmapDevice( aFrameSize, m_bTopDown, m_nScanlineFormat, nStride ); if (m_bDamageTracking) m_aFrame->setDamageTracker( + basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker ) ); // update device in existing graphics for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin(); commit df63131bfa652328f5b46bd638eb6f88deeeadf6 Author: Henry Castro <[email protected]> Date: Mon Sep 7 17:21:38 2015 -0400 preInitBootstrap call takes context Change-Id: I85b951f7d28d3d8af40b7d5f86b310021a079428 (cherry picked from commit 1c565696231ae5296a47bbb9df78d80d2da031f4) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index b6d8d05..a251adc 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1944,7 +1944,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char { InitVCL(); // pre-load all component libraries. - cppu::preInitBootstrap(); + cppu::preInitBootstrap(xContext); // Release Solar Mutex, lo_startmain thread should acquire it. Application::ReleaseSolarMutex(); } commit 58c4cd90d34aab5eb13380ef05d67ea7d2aaa225 Author: Henry Castro <[email protected]> Date: Sat Sep 12 12:11:43 2015 -0400 vcl: desktop terminate, to dispose objects In the preinit stage, the Desktop terminate() method is never called when lo_startmain thread is disposing objects. This produces debug assertions and osl assertions. It is forced to call terminate() method, when a tiled rendering case is active then it has a clean disposing objects process. However DBGGUI_DEINIT_SOLARMUTEXCHECK() check is moved at the end to prevent debug assertions solar mutex complains. Change-Id: I4a9b6398296d9150ab748a8d48868a08e7232909 (cherry picked from commit ba29b6ddf4c079a93a8484e95aa42daf2b54a54b) diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index 45b81a5..1182598 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -28,6 +28,7 @@ #include "tools/resmgr.hxx" #include "comphelper/processfactory.hxx" +#include "comphelper/lok.hxx" #include "unotools/syslocaleoptions.hxx" #include "vcl/svapp.hxx" @@ -445,8 +446,6 @@ void DeInitVCL() } pSVData->mpDefaultWin.disposeAndClear(); - DBGGUI_DEINIT_SOLARMUTEXCHECK(); - if ( pSVData->mpUnoWrapper ) { try @@ -454,6 +453,12 @@ void DeInitVCL() uno::Reference<frame::XDesktop2> const xDesktop = frame::Desktop::create( comphelper::getProcessComponentContext() ); xDesktop->addEventListener(new VCLUnoWrapperDeleter()); + + if (comphelper::LibreOfficeKit::isActive()) + { + SAL_WARN_IF(!xDesktop.is(), "desktop.app", "No Desktop interface"); + xDesktop->terminate(); + } } catch (uno::Exception const&) { @@ -567,6 +572,8 @@ void DeInitVCL() } EmbeddedFontsHelper::clearTemporaryFontFiles(); + + DBGGUI_DEINIT_SOLARMUTEXCHECK(); } // only one call is allowed commit 48eac22cce93c08d13022a7215b9549379453695 Author: Henry Castro <[email protected]> Date: Mon Sep 7 17:43:04 2015 -0400 vcl: assign NULL after deleting In the preinit stage, the VCL initialization is done by the parent process and when the lo_startmain thread de-initialize the VCL, some services are disposed early, and it causes segmentation violation. So it is ensured that pointers to service objetcs is set NULL after the delete. Change-Id: I65ecfc2d2694a981ec2986988efabdfd28d0cce4 (cherry picked from commit fca0980ec866279cc40ed1233bbddb2e4abe2fae) diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index 860c206..0352290 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -104,10 +104,10 @@ void ImplDeInitSVData() // delete global instance data if( pSVData->mpSettingsConfigItem ) - delete pSVData->mpSettingsConfigItem; + delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL; if( pSVData->mpDockingManager ) - delete pSVData->mpDockingManager; + delete pSVData->mpDockingManager, pSVData->mpDockingManager = NULL; if( pSVData->maCtrlData.mpFieldUnitStrings ) delete pSVData->maCtrlData.mpFieldUnitStrings, pSVData->maCtrlData.mpFieldUnitStrings = NULL; diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index bdea938..45b81a5 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -390,7 +390,7 @@ void DeInitVCL() delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL; if ( pSVData->maAppData.mpIdleMgr ) - delete pSVData->maAppData.mpIdleMgr; + delete pSVData->maAppData.mpIdleMgr, pSVData->maAppData.mpIdleMgr = NULL; Scheduler::ImplDeInitScheduler(); if ( pSVData->maWinData.mpMsgBoxImgList ) @@ -554,7 +554,11 @@ void DeInitVCL() pSVData->mpSalTimer = NULL; // Deinit Sal - DestroySalInstance( pSVData->mpDefInst ); + if (pSVData->mpDefInst) + { + DestroySalInstance( pSVData->mpDefInst ); + pSVData->mpDefInst = NULL; + } if( pOwnSvApp ) { commit 19349554e77a23c0cb551b886f51e854ca174df0 Author: Henry Castro <[email protected]> Date: Mon Sep 7 17:33:09 2015 -0400 vcl: add isInitVCL, to not initialize twice In the preinit stage, the VCL is initialized in the parent process and when the lo_startmain thread is started, the thread initialize VCL again. It is not necessary to initialize twice. Change-Id: I819cf0125afe7760c3f4d91c420d36a3a383902c (cherry picked from commit f0f7eb475ba402ceafa1d6f1956e7dfe7779615d) diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx index 72881a6..bdea938 100644 --- a/vcl/source/app/svmain.cxx +++ b/vcl/source/app/svmain.cxx @@ -91,6 +91,8 @@ using namespace ::com::sun::star; +bool isInitVCL(); + oslSignalAction SAL_CALL VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo* pInfo) { static bool bIn = false; @@ -160,7 +162,7 @@ int ImplSVMain() int nReturn = EXIT_FAILURE; - bool bInit = InitVCL(); + bool bInit = (!isInitVCL() ? InitVCL() : true); if( bInit ) { @@ -243,6 +245,14 @@ uno::Any SAL_CALL DesktopEnvironmentContext::getValueByName( const OUString& Nam return retVal; } +bool isInitVCL() +{ + ImplSVData* pSVData = ImplGetSVData(); + return pExceptionHandler != NULL && + pSVData->mpApp != NULL && + pSVData->mpDefInst != NULL; +} + bool InitVCL() { if( pExceptionHandler != NULL ) commit 267aa137bc89fd48aaae4cd90eff8bca52228fd2 Author: Henry Castro <[email protected]> Date: Mon Sep 7 17:17:22 2015 -0400 cppuhelper: add preInitBootstrap symbol In the preinit stage, the preInitBootstrap is called to load implementations for each service registered by the service manager. All service requests are: initial Component Context and the process service factory is set. However, some services require that VCL is properly initialized. Change-Id: Ib116e3da172b860f2df4d672f6181b5de0b7e6b2 (cherry picked from commit 78df8373b6442ee3d3b09101988817cf621c189b) diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx index b135b2c..602fdfb 100644 --- a/cppuhelper/source/defaultbootstrap.cxx +++ b/cppuhelper/source/defaultbootstrap.cxx @@ -42,19 +42,6 @@ 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 > @@ -120,8 +107,24 @@ cppu::defaultBootstrap_InitialComponentContext() } void -cppu::preInitBootstrap() +cppu::preInitBootstrap(css::uno::Reference< css::uno::XComponentContext > const & xContext) { - default_preInitBootstrap(getUnoIniUri()); + if (!xContext.is()) + throw css::uno::DeploymentException("preInit: XComponentContext is not created"); + + css::uno::Reference< css::uno::XInterface > xService; + xContext->getValueByName("/singletons/com.sun.star.lang.theServiceManager") >>= xService; + if (!xService.is()) + throw css::uno::DeploymentException("preInit: XMultiComponentFactory is not created"); + + rtl::Reference<cppuhelper::ServiceManager> aService(reinterpret_cast<cppuhelper::ServiceManager*>(xService.get())); + + // pre-requisites: + // In order to load implementations and invoke + // component factory it is required: + // 1) defaultBootstrap_InitialComponentContext() + // 2) comphelper::setProcessServiceFactory(xSFactory); + // 3) InitVCL() + aService->loadImplementations(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cppuhelper/source/gcc3.map b/cppuhelper/source/gcc3.map index 3d7a5c6..6344bc2 100644 --- a/cppuhelper/source/gcc3.map +++ b/cppuhelper/source/gcc3.map @@ -423,7 +423,7 @@ global: # enableChangeListenerNotification _ZN4cppu19OPropertySetHelper232enableChangeListenerNotificationEh; _ZThn*_N4cppu19OPropertySetHelper232enableChangeListenerNotificationEh; - _ZN4cppu16preInitBootstrapEv; + _ZN4cppu16preInitBootstrapERKN3com3sun4star3uno9ReferenceINS3_17XComponentContextEEE; } UDK_3.7; LIBO_UDK_3.9 { # LibO 3.7 diff --git a/include/cppuhelper/bootstrap.hxx b/include/cppuhelper/bootstrap.hxx index 94fa0a5..9481720 100644 --- a/include/cppuhelper/bootstrap.hxx +++ b/include/cppuhelper/bootstrap.hxx @@ -57,6 +57,16 @@ CPPUHELPER_DLLPUBLIC sal_Bool SAL_CALL installTypeDescriptionManager( CPPUHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > SAL_CALL defaultBootstrap_InitialComponentContext(); +/** preload component shared library with service manager upon + information from bootstrap variables. + + This function tries to find its parameters via these bootstrap variables: + + - UNO_SERVICES -- a space separated list of file urls of service rdbs + +*/ +CPPUHELPER_DLLPUBLIC void SAL_CALL +preInitBootstrap(css::uno::Reference< css::uno::XComponentContext > const & xContext); /** Bootstraps an initial component context with service manager upon information from an ini file. @@ -72,6 +82,7 @@ defaultBootstrap_InitialComponentContext(); @param iniFile ini filename to get bootstrap variables @return component context */ + CPPUHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > SAL_CALL defaultBootstrap_InitialComponentContext(const ::rtl::OUString & iniFile); commit 194f58dc19743e4f21789e09ff8220ce3ce68383 Author: Henry Castro <[email protected]> Date: Mon Sep 7 17:11:45 2015 -0400 cppuhelper: method 1, load implementations to invoke component factory In the preinit stage, for each library that is registered by the service manager, is loaded with the flag SAL_LOADMODULE_NOW and the component factory is invoked to initialize its data. Change-Id: Ie6f6d769b611c8440ddab802545e6bdc482d1476 (cherry picked from commit 0e008a27e7f4e9b08a7b2bbd33702df336f1bca4) diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx index ffed6ba..8be70aa 100644 --- a/cppuhelper/source/servicemanager.cxx +++ b/cppuhelper/source/servicemanager.cxx @@ -35,6 +35,8 @@ #include <cppuhelper/implbase1.hxx> #include <cppuhelper/implbase3.hxx> #include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/shlib.hxx> #include <osl/file.hxx> #include <rtl/ref.hxx> #include <rtl/uri.hxx> @@ -883,13 +885,16 @@ void cppuhelper::ServiceManager::loadImplementations() { rtl::OUString aUri; osl::MutexGuard g(rBHelper.rMutex); + css::uno::Environment aSourceEnv(css::uno::Environment::getCurrent()); + // loop all implementations for (Data::NamedImplementations::const_iterator iterator( data_.namedImplementations.begin()); iterator != data_.namedImplementations.end(); ++iterator) { try { + // expand absolute URI implementation component library aUri = cppu::bootstrap_expandUri(iterator->second->info->uri); } catch (css::lang::IllegalArgumentException& aError) @@ -902,13 +907,84 @@ void cppuhelper::ServiceManager::loadImplementations() 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")); + // load component library + osl::Module aModule(aUri, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL); + SAL_INFO("lok", "loaded component library " << aUri << ( aModule.is() ? " ok" : " no")); - // leak aModule - // osl_unloadModule(aModule); - if ( aModule ) + if (aModule.is() && + !iterator->second->info->environment.isEmpty()) + { + OUString aSymFactory; + oslGenericFunction fpFactory; + css::uno::Environment aTargetEnv; + css::uno::Reference<css::uno::XInterface> xFactory; + + if(iterator->second->info->constructor.isEmpty()) + { + // expand full name component factory symbol + if (iterator->second->info->prefix == "direct") + aSymFactory = iterator->second->info->name.replace('.', '_') + "_" COMPONENT_GETFACTORY; + else if (!iterator->second->info->prefix.isEmpty()) + aSymFactory = iterator->second->info->prefix + "_" COMPONENT_GETFACTORY; + else + aSymFactory = COMPONENT_GETFACTORY; + + // get function symbol component factory + fpFactory = aModule.getFunctionSymbol(aSymFactory); + if (fpFactory == 0) + { + throw css::loader::CannotActivateFactoryException( + ("no factory symbol \"" + aSymFactory + "\" in component library :" + aUri), + css::uno::Reference<css::uno::XInterface>()); + } + + aTargetEnv = cppuhelper::detail::getEnvironment(iterator->second->info->environment, iterator->second->info->name); + component_getFactoryFunc fpComponentFactory = reinterpret_cast<component_getFactoryFunc>(fpFactory); + + if (aSourceEnv.get() == aTargetEnv.get()) + { + // invoke function component factory + OString aImpl(rtl::OUStringToOString(iterator->second->info->name, RTL_TEXTENCODING_ASCII_US)); + xFactory.set(css::uno::Reference<css::uno::XInterface>(static_cast<css::uno::XInterface *>( + (*fpComponentFactory)(aImpl.getStr(), this, 0)), SAL_NO_ACQUIRE)); + } + } + else + { + // get function symbol component factory + fpFactory = aModule.getFunctionSymbol(iterator->second->info->constructor); + } + + css::uno::Reference<css::lang::XSingleComponentFactory> xSCFactory; + css::uno::Reference<css::lang::XSingleServiceFactory> xSSFactory; + + // query interface XSingleComponentFactory or XSingleServiceFactory + if (xFactory.is()) + { + xSCFactory.set(xFactory, css::uno::UNO_QUERY); + if (!xSCFactory.is()) + { + xSSFactory.set(xFactory, css::uno::UNO_QUERY); + if (!xSSFactory.is()) + { + throw css::uno::DeploymentException( + ("Implementation " + iterator->second->info->name + + " does not provide a constructor or factory"), + static_cast< cppu::OWeakObject * >(this)); + } + } + } + + if (!iterator->second->info->constructor.isEmpty() && fpFactory) + iterator->second->constructor = reinterpret_cast<ImplementationConstructorFn *>(fpFactory); + + iterator->second->factory1 = xSCFactory; + iterator->second->factory2 = xSSFactory; iterator->second->status = Data::Implementation::STATUS_LOADED; + + } + // leak aModule + aModule.release(); } } } commit 8e824a59965906077f1d1c39c5afa73b9fc4d650 Author: Ashod Nakashian <[email protected]> Date: Thu Jan 28 18:31:03 2016 -0500 Restoring preinit Change-Id: I65341c57d00308d246ec90deab8050b2c4bb3e61 (cherry picked from commit 62a2d525a7db09c7223a21907e1a0f4989398c15) diff --git a/cppuhelper/source/defaultbootstrap.cxx b/cppuhelper/source/defaultbootstrap.cxx index 1fbbf8f..b135b2c 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 12c29834a..3d7a5c6 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 2140a2f..ffed6ba 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 903084b..ddf85965f 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 ed5057b..28d83f8 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 a40285b..b6d8d05 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> @@ -1797,6 +1799,7 @@ static bool initialize_uno(const OUString& aAppProgramURL) #endif xContext = cppu::defaultBootstrap_InitialComponentContext(); + if (!xContext.is()) { gImpl->maLastExceptionMsg = "XComponentContext could not be created"; @@ -1835,6 +1838,9 @@ static void lo_startmain(void*) { osl_setThreadName("lo_startmain"); + if (GetpApp()) + Application::GetSolarMutex().tryToAcquire(); + soffice_main(); } @@ -1863,19 +1869,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; @@ -1898,22 +1923,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"); + + 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(); - // 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(); + 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. @@ -1934,27 +1971,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) { @@ -1988,6 +2032,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) { bool bSuccess = false; diff --git a/include/cppuhelper/bootstrap.hxx b/include/cppuhelper/bootstrap.hxx index debddcf..94fa0a5 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 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" ); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
