Use an XInitialization-based channel to request service mgr pre-init

...instead of private cppu::preInitBootstrap function

Change-Id: Id0e6fcf721b697c993e5acffaf7836452cfa9750
Reviewed-on: https://gerrit.libreoffice.org/22699
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
Tested-by: Tor Lillqvist <tml@collabora.com>
This commit is contained in:
Stephan Bergmann
2016-02-25 15:33:22 +01:00
committed by Tor Lillqvist
parent d0b09f41ef
commit 79c11bb56e
7 changed files with 159 additions and 187 deletions

View File

@@ -18,7 +18,6 @@
#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>
@@ -108,26 +107,4 @@ cppu::defaultBootstrap_InitialComponentContext()
return defaultBootstrap_InitialComponentContext(getUnoIniUri());
}
void
cppu::preInitBootstrap(css::uno::Reference< css::uno::XComponentContext > const & xContext)
{
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->loadAllImplementations();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -436,8 +436,3 @@ GLIBCXX_3.4 {
_ZGVNSt7num_put*; _ZNSt7num_put*;
_ZNSs4_Rep20_S_empty_rep_storageE;
};
PRIVATE_1.0 { # LibO 5.2
global:
_ZN4cppu16preInitBootstrapERKN3com3sun4star3uno9ReferenceINS3_17XComponentContextEEE;
};

View File

@@ -878,118 +878,6 @@ void cppuhelper::ServiceManager::loadImplementation(
}
}
void cppuhelper::ServiceManager::loadAllImplementations()
{
#ifdef DISABLE_DYNLOADING
abort();
#else
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)
{
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)
{
// load component library
osl::Module aModule(aUri, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL);
SAL_INFO("lok", "loaded component library " << aUri << ( aModule.is() ? " ok" : " no"));
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 == nullptr)
{
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, nullptr)), 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();
}
}
#endif
}
void cppuhelper::ServiceManager::disposing() {
std::vector< css::uno::Reference<css::lang::XComponent> > sngls;
std::vector< css::uno::Reference< css::lang::XComponent > > comps;
@@ -1051,6 +939,22 @@ void cppuhelper::ServiceManager::disposing() {
}
}
void cppuhelper::ServiceManager::initialize(
css::uno::Sequence<css::uno::Any> const & aArguments)
throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
{
OUString arg;
if (aArguments.getLength() == 1 && (aArguments[0] >>= arg)
&& arg == "preload")
{
preloadImplementations();
} else {
throw css::lang::IllegalArgumentException(
"invalid ServiceManager::initialize argument",
css::uno::Reference<css::uno::XInterface>(), 0);
}
}
rtl::OUString cppuhelper::ServiceManager::getImplementationName()
throw (css::uno::RuntimeException, std::exception)
{
@@ -1989,4 +1893,115 @@ cppuhelper::ServiceManager::findServiceImplementation(
return impl;
}
void cppuhelper::ServiceManager::preloadImplementations() {
#ifdef DISABLE_DYNLOADING
abort();
#else
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)
{
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)
{
// load component library
osl::Module aModule(aUri, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL);
SAL_INFO("lok", "loaded component library " << aUri << ( aModule.is() ? " ok" : " no"));
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 == nullptr)
{
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, nullptr)), 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();
}
}
#endif
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -23,6 +23,7 @@
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
@@ -30,7 +31,7 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <cppuhelper/basemutex.hxx>
#include <cppuhelper/compbase8.hxx>
#include <cppuhelper/compbase.hxx>
#include <osl/mutex.hxx>
#include <registry/registry.hxx>
#include <rtl/ustring.hxx>
@@ -50,11 +51,12 @@ typedef css::uno::XInterface * SAL_CALL ImplementationConstructorFn(
}
typedef cppu::WeakComponentImplHelper8<
typedef cppu::WeakComponentImplHelper<
css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
css::lang::XMultiComponentFactory, css::container::XSet,
css::container::XContentEnumerationAccess, css::beans::XPropertySet,
css::beans::XPropertySetInfo, css::lang::XEventListener >
css::beans::XPropertySetInfo, css::lang::XEventListener,
css::lang::XInitialization>
ServiceManagerBase;
class ServiceManager:
@@ -203,8 +205,6 @@ public:
css::uno::Reference< css::uno::XComponentContext > const & context,
std::shared_ptr< Data::Implementation > & implementation);
void loadAllImplementations();
private:
virtual ~ServiceManager();
@@ -333,6 +333,11 @@ private:
virtual void SAL_CALL disposing(css::lang::EventObject const & Source)
throw (css::uno::RuntimeException, std::exception) override;
virtual void SAL_CALL initialize(
css::uno::Sequence<css::uno::Any> const & aArguments)
throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
override;
// needs to be called with rBHelper.rMutex locked:
bool isDisposed() { return rBHelper.bDisposed || rBHelper.bInDispose; }
@@ -377,6 +382,8 @@ private:
css::uno::Reference< css::uno::XComponentContext > const & context,
rtl::OUString const & specifier);
void preloadImplementations();
css::uno::Reference< css::uno::XComponentContext > context_;
Data data_;
};

View File

@@ -59,7 +59,6 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\
ucbhelper \
utl \
vcl \
xmlreader \
$(gb_UWINAPI) \
))

View File

@@ -28,7 +28,6 @@
#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>
@@ -48,8 +47,6 @@
#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>
@@ -1920,8 +1917,27 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
if (eStage == PRE_INIT)
{
InitVCL();
// pre-load all component libraries.
cppu::preInitBootstrap(xContext);
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");
css::uno::Reference<css::lang::XInitialization> aService(
xService, css::uno::UNO_QUERY_THROW);
// pre-requisites:
// In order to load implementations and invoke
// component factory it is required:
// 1) defaultBootstrap_InitialComponentContext()
// 2) comphelper::setProcessServiceFactory(xSFactory);
// 3) InitVCL()
aService->initialize({css::uno::makeAny<OUString>("preload")});
// Release Solar Mutex, lo_startmain thread should acquire it.
Application::ReleaseSolarMutex();
}

View File

@@ -1,37 +0,0 @@
/* -*- 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
/** Preload all shared library components 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);
#endif // LIBO_INTERNAL_ONLY
} // namespace cppu
#endif // INCLUDED_CPPUHELPER_DETAIL_PREINIT_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */