diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-01-16 15:29:41 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-01-16 18:40:05 +0100 |
commit | 997d21183322a0a94b96868073808841d2773902 (patch) | |
tree | 250e92ab34ac79b4c3a8624a5e3ca8afb8df4d54 /cppuhelper/source | |
parent | 9c46e4069db51ab0fc8b3e197d27b5f947a3fdeb (diff) |
Support for singleton constructor functions
The service manager now keeps track of instances of singleton implementations
(i.e., implementations whose XML description lists at least one
<singleton ...>). These instances will be disposed either when the service
manager is disposed, or, for instances that have been instantiated into the
component context's /singleton/* map, when the component context is disposed.
This change allows to use constructor functions for such singleton
implementations, too.
Change-Id: I220c9ddc9824e4d7f7556daefb599e2ec36b0e6c
Diffstat (limited to 'cppuhelper/source')
-rw-r--r-- | cppuhelper/source/servicemanager.cxx | 456 | ||||
-rw-r--r-- | cppuhelper/source/servicemanager.hxx | 31 |
2 files changed, 320 insertions, 167 deletions
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx index d7ab48ac447a..9bc31138447b 100644 --- a/cppuhelper/source/servicemanager.cxx +++ b/cppuhelper/source/servicemanager.cxx @@ -519,6 +519,58 @@ css::beans::Property getDefaultContextProperty() { css::beans::PropertyAttribute::READONLY); } +class SingletonFactory: + public cppu::WeakImplHelper1<css::lang::XSingleComponentFactory>, + private boost::noncopyable +{ +public: + SingletonFactory( + rtl::Reference< cppuhelper::ServiceManager > const & manager, + boost::shared_ptr< + cppuhelper::ServiceManager::Data::Implementation > const & + implementation): + manager_(manager), implementation_(implementation) + { assert(manager.is()); assert(implementation.get() != 0); } + +private: + virtual ~SingletonFactory() {} + + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL + createInstanceWithContext( + css::uno::Reference< css::uno::XComponentContext > const & Context) + throw (css::uno::Exception, css::uno::RuntimeException); + + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL + createInstanceWithArgumentsAndContext( + css::uno::Sequence< css::uno::Any > const & Arguments, + css::uno::Reference< css::uno::XComponentContext > const & Context) + throw (css::uno::Exception, css::uno::RuntimeException); + + rtl::Reference< cppuhelper::ServiceManager > manager_; + boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > + implementation_; +}; + +css::uno::Reference< css::uno::XInterface > +SingletonFactory::createInstanceWithContext( + css::uno::Reference< css::uno::XComponentContext > const & Context) + throw (css::uno::Exception, css::uno::RuntimeException) +{ + manager_->loadImplementation(Context, implementation_); + return implementation_->createInstance(Context, true); +} + +css::uno::Reference< css::uno::XInterface > +SingletonFactory::createInstanceWithArgumentsAndContext( + css::uno::Sequence< css::uno::Any > const & Arguments, + css::uno::Reference< css::uno::XComponentContext > const & Context) + throw (css::uno::Exception, css::uno::RuntimeException) +{ + manager_->loadImplementation(Context, implementation_); + return implementation_->createInstanceWithArguments( + Context, true, Arguments); +} + class ImplementationWrapper: public cppu::WeakImplHelper3< css::lang::XSingleComponentFactory, css::lang::XSingleServiceFactory, @@ -529,10 +581,10 @@ public: ImplementationWrapper( rtl::Reference< cppuhelper::ServiceManager > const & manager, boost::shared_ptr< - cppuhelper::ServiceManager::Data::ImplementationInfo > const & - info): - manager_(manager), info_(info), loaded_(false), constructor_(0) - { assert(manager.is() && info.get() != 0); } + cppuhelper::ServiceManager::Data::Implementation > const & + implementation): + manager_(manager), implementation_(implementation) + { assert(manager.is()); assert(implementation.get() != 0); } private: virtual ~ImplementationWrapper() {} @@ -565,18 +617,9 @@ private: virtual css::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException); - void loadImplementation( - css::uno::Reference< css::uno::XComponentContext > const & context); - rtl::Reference< cppuhelper::ServiceManager > manager_; - boost::shared_ptr< cppuhelper::ServiceManager::Data::ImplementationInfo > - info_; - - osl::Mutex mutex_; - bool loaded_; - cppuhelper::ImplementationConstructorFn * constructor_; - css::uno::Reference< css::lang::XSingleComponentFactory > factory1_; - css::uno::Reference< css::lang::XSingleServiceFactory > factory2_; + boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation > + implementation_; }; css::uno::Reference< css::uno::XInterface > @@ -584,15 +627,8 @@ ImplementationWrapper::createInstanceWithContext( css::uno::Reference< css::uno::XComponentContext > const & Context) throw (css::uno::Exception, css::uno::RuntimeException) { - loadImplementation(Context); - return constructor_ != 0 - ? css::uno::Reference<css::uno::XInterface>( - (*constructor_)( - Context.get(), css::uno::Sequence<css::uno::Any>()), - SAL_NO_ACQUIRE) - : factory1_.is() - ? factory1_->createInstanceWithContext(Context) - : factory2_->createInstance(); + manager_->loadImplementation(Context, implementation_); + return implementation_->createInstance(Context, false); } css::uno::Reference< css::uno::XInterface > @@ -601,19 +637,9 @@ ImplementationWrapper::createInstanceWithArgumentsAndContext( css::uno::Reference< css::uno::XComponentContext > const & Context) throw (css::uno::Exception, css::uno::RuntimeException) { - loadImplementation(Context); - if (constructor_ != 0) { - css::uno::Reference<css::uno::XInterface> xRet( - (*constructor_)(Context.get(), Arguments), SAL_NO_ACQUIRE); - css::uno::Reference<css::lang::XInitialization> xInit( - xRet, css::uno::UNO_QUERY); - if (xInit.is()) - xInit->initialize(Arguments); - return xRet; - } else - return factory1_.is() - ? factory1_->createInstanceWithArgumentsAndContext(Arguments, Context) - : factory2_->createInstanceWithArguments(Arguments); + manager_->loadImplementation(Context, implementation_); + return implementation_->createInstanceWithArguments( + Context, false, Arguments); } css::uno::Reference< css::uno::XInterface > @@ -635,7 +661,7 @@ ImplementationWrapper::createInstanceWithArguments( rtl::OUString ImplementationWrapper::getImplementationName() throw (css::uno::RuntimeException) { - return info_->name; + return implementation_->info->name; } sal_Bool ImplementationWrapper::supportsService(rtl::OUString const & ServiceName) @@ -648,58 +674,149 @@ css::uno::Sequence< rtl::OUString > ImplementationWrapper::getSupportedServiceNames() throw (css::uno::RuntimeException) { - if (info_->services.size() > static_cast< sal_uInt32 >(SAL_MAX_INT32)) { + if (implementation_->info->services.size() + > static_cast< sal_uInt32 >(SAL_MAX_INT32)) + { throw css::uno::RuntimeException( - "Implementation " + info_->name + " supports too many services", + ("Implementation " + implementation_->info->name + + " supports too many services"), static_cast< cppu::OWeakObject * >(this)); } css::uno::Sequence< rtl::OUString > names( - static_cast< sal_Int32 >(info_->services.size())); + static_cast< sal_Int32 >(implementation_->info->services.size())); sal_Int32 i = 0; for (std::vector< rtl::OUString >::const_iterator j( - info_->services.begin()); - j != info_->services.end(); ++j) + implementation_->info->services.begin()); + j != implementation_->info->services.end(); ++j) { names[i++] = *j; } return names; } -void ImplementationWrapper::loadImplementation( - css::uno::Reference< css::uno::XComponentContext > const & context) +} + +css::uno::Reference<css::uno::XInterface> +cppuhelper::ServiceManager::Data::Implementation::createInstance( + css::uno::Reference<css::uno::XComponentContext> const & context, + bool singletonRequest) { - { - osl::MutexGuard g(mutex_); - if (loaded_) { - return; + if (info->singletons.empty()) { + assert(!singletonRequest); + if (constructor != 0) { + return css::uno::Reference<css::uno::XInterface>( + (*constructor)( + context.get(), css::uno::Sequence<css::uno::Any>()), + SAL_NO_ACQUIRE); + } + if (factory1.is()) { + return factory1->createInstanceWithContext(context); + } + if (factory2.is()) { + return factory2->createInstance(); } - } - cppuhelper::ImplementationConstructorFn * ctor = 0; - css::uno::Reference< css::lang::XSingleComponentFactory > f1; - css::uno::Reference< css::lang::XSingleServiceFactory > f2; - //TODO: There is a race here, as the relevant service factory can already - // have been removed and loading can thus fail, as the entity from which to - // load can disappear once the service factory is removed: - manager_->loadImplementation(context, info_, &ctor, &f1, &f2); - if (ctor == 0 && !f1.is() && !f2.is()) { throw css::uno::DeploymentException( - ("Implementation " + info_->name + ("Implementation " + info->name + " does not provide a constructor or factory"), - static_cast< cppu::OWeakObject * >(this)); - } - osl::MutexGuard g(mutex_); - if (!loaded_) { - loaded_ = true; - constructor_ = ctor; - factory1_ = f1; - factory2_ = f2; + css::uno::Reference<css::uno::XInterface>()); + } else { + osl::MutexGuard g(mutex); //TODO: must be a non-recursive mutex + if (singleton.is()) { + if (singletonRequest) { + dispose = false; + } + return singleton; + } + if (constructor != 0) { + singleton.set( + (*constructor)( + context.get(), css::uno::Sequence<css::uno::Any>()), + SAL_NO_ACQUIRE); + } else if (factory1.is()) { + singleton = factory1->createInstanceWithContext(context); + } else if (factory2.is()) { + singleton = factory2->createInstance(); + } else { + throw css::uno::DeploymentException( + ("Implementation " + info->name + + " does not provide a constructor or factory"), + css::uno::Reference<css::uno::XInterface>()); + } + dispose = singleton.is() && !singletonRequest; + return singleton; } } +css::uno::Reference<css::uno::XInterface> +cppuhelper::ServiceManager::Data::Implementation::createInstanceWithArguments( + css::uno::Reference<css::uno::XComponentContext> const & context, + bool singletonRequest, css::uno::Sequence<css::uno::Any> const & arguments) +{ + if (info->singletons.empty()) { + assert(!singletonRequest); + if (constructor != 0) { + //HACK: The constructor will either observe arguments and return + // inst that does not implement XInitialization (or null), or ignore + // arguments and return inst that implements XInitialization; this + // should be removed again once XInitialization-based + // implementations have become rare: + css::uno::Reference<css::uno::XInterface> inst( + (*constructor)(context.get(), arguments), SAL_NO_ACQUIRE); + css::uno::Reference<css::lang::XInitialization> init( + inst, css::uno::UNO_QUERY); + if (init.is()) { + init->initialize(arguments); + } + return inst; + } + if (factory1.is()) { + return factory1->createInstanceWithArgumentsAndContext( + arguments, context); + } + if (factory2.is()) { + return factory2->createInstanceWithArguments(arguments); + } + throw css::uno::DeploymentException( + "Implementation " + info->name + " does not provide a factory", + css::uno::Reference<css::uno::XInterface>()); + } else { + osl::MutexGuard g(mutex); //TODO: must be a non-recursive mutex + if (singleton.is()) { + SAL_WARN( + "cppuhelper", + "createInstanceWithArguments request for already instantiated" + " singleton implementation " << info->name); + if (singletonRequest) { + dispose = false; + } + return singleton; + } + if (constructor != 0) { + //HACK: see above + singleton.set( + (*constructor)(context.get(), arguments), SAL_NO_ACQUIRE); + css::uno::Reference<css::lang::XInitialization> init( + singleton, css::uno::UNO_QUERY); + if (init.is()) { + init->initialize(arguments); + } + } else if (factory1.is()) { + singleton = factory1->createInstanceWithArgumentsAndContext( + arguments, context); + } else if (factory2.is()) { + singleton = factory2->createInstanceWithArguments(arguments); + } else { + throw css::uno::DeploymentException( + "Implementation " + info->name + " does not provide a factory", + css::uno::Reference<css::uno::XInterface>()); + } + dispose = singleton.is() && !singletonRequest; + return singleton; + } } void cppuhelper::ServiceManager::addSingletonContextEntries( - std::vector< cppu::ContextEntry_Init > * entries) const + std::vector< cppu::ContextEntry_Init > * entries) { assert(entries != 0); for (Data::ImplementationMap::const_iterator i(data_.singletons.begin()); @@ -714,44 +831,50 @@ void cppuhelper::ServiceManager::addSingletonContextEntries( entries->push_back( cppu::ContextEntry_Init( "/singletons/" + i->first, - css::uno::makeAny(i->second[0]->info->name), true)); + css::uno::makeAny< + css::uno::Reference<css::lang::XSingleComponentFactory> >( + new SingletonFactory(this, i->second[0])), + true)); } } void cppuhelper::ServiceManager::loadImplementation( css::uno::Reference< css::uno::XComponentContext > const & context, - boost::shared_ptr< Data::ImplementationInfo > const & info, - ImplementationConstructorFn ** constructor, - css::uno::Reference< css::lang::XSingleComponentFactory > * factory1, - css::uno::Reference< css::lang::XSingleServiceFactory > * factory2) + boost::shared_ptr< Data::Implementation > & implementation) { - assert( - info.get() != 0 && constructor != 0 && *constructor == 0 - && factory1 != 0 && !factory1->is() && factory2 != 0 - && !factory2->is()); + assert(implementation.get() != 0); + { + osl::MutexGuard g(rBHelper.rMutex); + if (implementation->status == Data::Implementation::STATUS_LOADED) { + return; + } + } rtl::OUString uri; try { - uri = cppu::bootstrap_expandUri(info->uri); + uri = cppu::bootstrap_expandUri(implementation->info->uri); } catch (css::lang::IllegalArgumentException & e) { throw css::uno::DeploymentException( - "Cannot expand URI" + info->uri + ": " + e.Message, + "Cannot expand URI" + implementation->info->uri + ": " + e.Message, static_cast< cppu::OWeakObject * >(this)); } + cppuhelper::ImplementationConstructorFn * ctor = 0; css::uno::Reference< css::uno::XInterface > f0; // Special handling of SharedLibrary loader, with support for environment, // constructor, and prefix arguments: - if (!info->alienContext.is() - && info->loader == "com.sun.star.loader.SharedLibrary") + if (!implementation->info->alienContext.is() + && implementation->info->loader == "com.sun.star.loader.SharedLibrary") { cppuhelper::detail::loadSharedLibComponentFactory( - uri, info->environment, info->prefix, info->name, info->constructor, - this, constructor, &f0); - if (constructor != 0 && *constructor != 0) { - assert(!info->environment.isEmpty()); + uri, implementation->info->environment, + implementation->info->prefix, implementation->info->name, + implementation->info->constructor, this, &ctor, &f0); + if (ctor != 0) { + assert(!implementation->info->environment.isEmpty()); css::uno::Environment curEnv(css::uno::Environment::getCurrent()); css::uno::Environment env( cppuhelper::detail::getEnvironment( - info->environment, info->name)); + implementation->info->environment, + implementation->info->name)); if (!(curEnv.is() && env.is())) { throw css::uno::DeploymentException( "cannot get environments", @@ -763,21 +886,23 @@ void cppuhelper::ServiceManager::loadImplementation( } } else { SAL_WARN_IF( - !info->environment.isEmpty(), "cppuhelper", - "Loader " << info->loader << " and non-empty environment " - << info->environment); + !implementation->info->environment.isEmpty(), "cppuhelper", + "Loader " << implementation->info->loader + << " and non-empty environment " + << implementation->info->environment); SAL_WARN_IF( - !info->prefix.isEmpty(), "cppuhelper", - "Loader " << info->loader << " and non-empty constructor " - << info->constructor); + !implementation->info->prefix.isEmpty(), "cppuhelper", + "Loader " << implementation->info->loader + << " and non-empty constructor " + << implementation->info->constructor); SAL_WARN_IF( - !info->prefix.isEmpty(), "cppuhelper", - "Loader " << info->loader << " and non-empty prefix " - << info->prefix); + !implementation->info->prefix.isEmpty(), "cppuhelper", + "Loader " << implementation->info->loader + << " and non-empty prefix " << implementation->info->prefix); css::uno::Reference< css::uno::XComponentContext > ctxt; css::uno::Reference< css::lang::XMultiComponentFactory > smgr; - if (info->alienContext.is()) { - ctxt = info->alienContext; + if (implementation->info->alienContext.is()) { + ctxt = implementation->info->alienContext; smgr = css::uno::Reference< css::lang::XMultiComponentFactory >( ctxt->getServiceManager(), css::uno::UNO_SET_THROW); } else { @@ -786,28 +911,69 @@ void cppuhelper::ServiceManager::loadImplementation( smgr = this; } css::uno::Reference< css::loader::XImplementationLoader > loader( - smgr->createInstanceWithContext(info->loader, ctxt), + smgr->createInstanceWithContext(implementation->info->loader, ctxt), css::uno::UNO_QUERY_THROW); f0 = loader->activate( - info->name, rtl::OUString(), uri, + implementation->info->name, rtl::OUString(), uri, css::uno::Reference< css::registry::XRegistryKey >()); } - factory1->set(f0, css::uno::UNO_QUERY); - if (!factory1->is()) { - factory2->set(f0, css::uno::UNO_QUERY); + css::uno::Reference<css::lang::XSingleComponentFactory> f1; + css::uno::Reference<css::lang::XSingleServiceFactory> f2; + if (ctor == 0) { + f1.set(f0, css::uno::UNO_QUERY); + if (!f1.is()) { + f2.set(f0, css::uno::UNO_QUERY); + if (!f2.is()) { + throw css::uno::DeploymentException( + ("Implementation " + implementation->info->name + + " does not provide a constructor or factory"), + static_cast< cppu::OWeakObject * >(this)); + } + } + } + //TODO: There is a race here, as the relevant service factory can be removed + // while the mutex is unlocked and loading can thus fail, as the entity from + // which to load can disappear once the service factory is removed. + osl::MutexGuard g(rBHelper.rMutex); + if (!(isDisposed() + || implementation->status == Data::Implementation::STATUS_LOADED)) + { + implementation->status = Data::Implementation::STATUS_LOADED; + implementation->constructor = ctor; + implementation->factory1 = f1; + implementation->factory2 = f2; } } void cppuhelper::ServiceManager::disposing() { + std::vector< css::uno::Reference<css::uno::XInterface> > sngls; std::vector< css::uno::Reference< css::lang::XComponent > > comps; Data clear; { osl::MutexGuard g(rBHelper.rMutex); + for (Data::NamedImplementations::const_iterator i( + data_.namedImplementations.begin()); + i != data_.namedImplementations.end(); ++i) + { + assert(i->second.get() != 0); + if (!i->second->info->singletons.empty()) { + osl::MutexGuard g2(i->second->mutex); + if (i->second->dispose) { + sngls.push_back(i->second->singleton); + } + } + } for (Data::DynamicImplementations::const_iterator i( data_.dynamicImplementations.begin()); i != data_.dynamicImplementations.end(); ++i) { assert(i->second.get() != 0); + if (!i->second->info->singletons.empty()) { + osl::MutexGuard g2(i->second->mutex); + if (i->second->dispose) { + sngls.push_back(i->second->singleton); + } + } if (i->second->component.is()) { comps.push_back(i->second->component); } @@ -818,6 +984,24 @@ void cppuhelper::ServiceManager::disposing() { data_.singletons.swap(clear.singletons); } for (std::vector< + css::uno::Reference<css::uno::XInterface> >::const_iterator i( + sngls.begin()); + i != sngls.end(); ++i) + { + css::uno::Reference<css::lang::XComponent> comp( + *i, css::uno::UNO_QUERY); + if (comp.is()) { + try { + comp->dispose(); + } catch (css::uno::RuntimeException & e) { + SAL_WARN( + "cppuhelper", + "Ignoring RuntimeException \"" << e.Message + << "\" while disposing singleton"); + } + } + } + for (std::vector< css::uno::Reference< css::lang::XComponent > >::const_iterator i( comps.begin()); i != comps.end(); ++i) @@ -903,23 +1087,9 @@ cppuhelper::ServiceManager::createInstanceWithContext( { boost::shared_ptr< Data::Implementation > impl( findServiceImplementation(Context, aServiceSpecifier)); - if (impl.get() == 0) { - return css::uno::Reference< css::uno::XInterface >(); - } - if (impl->constructor != 0) { - return css::uno::Reference<css::uno::XInterface>( - (*impl->constructor)( - Context.get(), css::uno::Sequence<css::uno::Any>()), - SAL_NO_ACQUIRE); - } else if (impl->factory1.is()) { - return impl->factory1->createInstanceWithContext(Context); - } - if (impl->factory2.is()) { - return impl->factory2->createInstance(); - } - throw css::uno::DeploymentException( - "Implementation " + impl->info->name + " does not provide a factory", - static_cast< cppu::OWeakObject * >(this)); + return impl.get() == 0 + ? css::uno::Reference< css::uno::XInterface >() + : impl->createInstance(Context, false); } css::uno::Reference< css::uno::XInterface > @@ -931,28 +1101,9 @@ cppuhelper::ServiceManager::createInstanceWithArgumentsAndContext( { boost::shared_ptr< Data::Implementation > impl( findServiceImplementation(Context, ServiceSpecifier)); - if (impl.get() == 0) { - return css::uno::Reference< css::uno::XInterface >(); - } - if (impl->constructor != 0) { - css::uno::Reference<css::uno::XInterface> xRet( - (*impl->constructor)(Context.get(), Arguments), - SAL_NO_ACQUIRE); - css::uno::Reference<css::lang::XInitialization> xInit( - xRet, css::uno::UNO_QUERY); - if (xInit.is()) - xInit->initialize(Arguments); - return xRet; - } else if (impl->factory1.is()) { - return impl->factory1->createInstanceWithArgumentsAndContext( - Arguments, Context); - } - if (impl->factory2.is()) { - return impl->factory2->createInstanceWithArguments(Arguments); - } - throw css::uno::DeploymentException( - "Implementation " + impl->info->name + " does not provide a factory", - static_cast< cppu::OWeakObject * >(this)); + return impl.get() == 0 + ? css::uno::Reference< css::uno::XInterface >() + : impl->createInstanceWithArguments(Context, false, Arguments); } css::uno::Type cppuhelper::ServiceManager::getElementType() @@ -1126,15 +1277,15 @@ cppuhelper::ServiceManager::createContentEnumeration( factories.clear(); break; } - if (!impl->loaded) { + if (impl->status == Data::Implementation::STATUS_NEW) { // Postpone actual implementation instantiation as long as // possible (so that e.g. opening LO's "Tools - Macros" menu // does not try to instantiate a JVM, which can lead to a // synchronous error dialog when no JVM is specified, and // showing the dialog while hovering over a menu can cause // trouble): - impl->factory1 = new ImplementationWrapper(this, impl->info); - impl->loaded = true; + impl->factory1 = new ImplementationWrapper(this, *i); + impl->status = Data::Implementation::STATUS_WRAPPER; } } if (impl->factory1.is()) { @@ -1784,23 +1935,10 @@ cppuhelper::ServiceManager::findServiceImplementation( impl = i->second[0]; } assert(impl.get() != 0); - loaded = impl->loaded; + loaded = impl->status == Data::Implementation::STATUS_LOADED; } - //TODO: There is a race here, as the relevant service factory can be removed - // while the mutex is unlocked and loading can thus fail, as the entity from - // which to load can disappear once the service factory is removed. if (!loaded) { - cppuhelper::ImplementationConstructorFn * ctor = 0; - css::uno::Reference< css::lang::XSingleComponentFactory > f1; - css::uno::Reference< css::lang::XSingleServiceFactory > f2; - loadImplementation(context, impl->info, &ctor, &f1, &f2); - osl::MutexGuard g(rBHelper.rMutex); - if (!(isDisposed() || impl->loaded)) { - impl->loaded = true; - impl->constructor = ctor; - impl->factory1 = f1; - impl->factory2 = f2; - } + loadImplementation(context, impl); } return impl; } diff --git a/cppuhelper/source/servicemanager.hxx b/cppuhelper/source/servicemanager.hxx index 74f2f4acb51f..cefeb316bd9c 100644 --- a/cppuhelper/source/servicemanager.hxx +++ b/cppuhelper/source/servicemanager.hxx @@ -105,7 +105,7 @@ public: new ImplementationInfo( name, loader, uri, environment, constructorName, prefix, alienContext, rdbFile)), - constructor(0), loaded(false) + constructor(0), status(STATUS_NEW) {} Implementation( @@ -118,15 +118,33 @@ public: theComponent): info(new ImplementationInfo(name)), constructor(0), factory1(theFactory1), factory2(theFactory2), - component(theComponent), loaded(true) + component(theComponent), status(STATUS_LOADED) {} + css::uno::Reference<css::uno::XInterface> createInstance( + css::uno::Reference<css::uno::XComponentContext> const & + context, + bool singletonRequest); + + css::uno::Reference<css::uno::XInterface> + createInstanceWithArguments( + css::uno::Reference<css::uno::XComponentContext> const & + context, + bool singletonRequest, + css::uno::Sequence<css::uno::Any> const & arguments); + + enum Status { STATUS_NEW, STATUS_WRAPPER, STATUS_LOADED }; + boost::shared_ptr< ImplementationInfo > info; ImplementationConstructorFn * constructor; css::uno::Reference< css::lang::XSingleComponentFactory > factory1; css::uno::Reference< css::lang::XSingleServiceFactory > factory2; css::uno::Reference< css::lang::XComponent > component; - bool loaded; + Status status; + + osl::Mutex mutex; + css::uno::Reference<css::uno::XInterface> singleton; + bool dispose; }; typedef std::map< rtl::OUString, boost::shared_ptr< Implementation > > @@ -166,7 +184,7 @@ public: } void addSingletonContextEntries( - std::vector< cppu::ContextEntry_Init > * entries) const; + std::vector< cppu::ContextEntry_Init > * entries); css::uno::Reference< css::uno::XComponentContext > getContext() const { assert(context_.is()); @@ -175,10 +193,7 @@ public: void loadImplementation( css::uno::Reference< css::uno::XComponentContext > const & context, - boost::shared_ptr< Data::ImplementationInfo > const & info, - ImplementationConstructorFn ** constructor, - css::uno::Reference< css::lang::XSingleComponentFactory > * factory1, - css::uno::Reference< css::lang::XSingleServiceFactory > * factory2); + boost::shared_ptr< Data::Implementation > & implementation); private: virtual ~ServiceManager() {} |