Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ServiceLoader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ServiceLoader.cc (C) 2000-2022 */
9/* */
10/* Service loader for available services in the code. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/Collection.h"
16#include "arcane/utils/Enumerator.h"
17#include "arcane/utils/String.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/CriticalSection.h"
20
21#include "arcane/core/IServiceLoader.h"
22#include "arcane/core/IServiceMng.h"
23#include "arcane/core/ISubDomain.h"
24#include "arcane/core/Service.h"
25#include "arcane/core/IModuleFactory.h"
26#include "arcane/core/IModule.h"
27
28#include "arcane/core/ServiceInfo.h"
29#include "arcane/core/IService.h"
30
31#include <typeinfo>
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
45class ServiceLoader
46: public IServiceLoader
47{
48 public:
49 public:
50
51 ServiceLoader();
52
53 ~ServiceLoader() override;
54
58 void loadSessionServices(ISession*) override;
60 void loadSubDomainServices(ISubDomain* parent) override;
62 void loadModules(ISubDomain* sd, bool all_modules) override;
63
64 void initializeModuleFactories(ISubDomain* sd) override;
65
66 bool loadSingletonService(ISubDomain* sd, const String& name) override;
67
68 private:
69
70 void _loadServices(IApplication* application, const ServiceBuildInfoBase& sbib);
72 _createSingletonInstance(IServiceMng* sm, IServiceInfo* si, const ServiceBuildInfoBase& sbi);
73};
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78ServiceLoader::
79ServiceLoader()
80{
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86ServiceLoader::
87~ServiceLoader()
88{
89}
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94extern "C++" IServiceLoader*
95arcaneCreateServiceLoader()
96{
97 IServiceLoader* icl = new ServiceLoader();
98 return icl;
99}
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
106{
107 ITraceMng* trace = parent->traceMng();
108 trace->log() << "Loading Application Services";
109 _loadServices(parent, ServiceBuildInfoBase(parent));
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
117{
118 ITraceMng* trace = parent->traceMng();
119 trace->log() << "Loading Session Services";
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
128{
129 ITraceMng* trace = parent->traceMng();
130 trace->log() << "Loading SubDomain Services";
131 {
133 }
134}
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
139SingletonServiceInstanceRef ServiceLoader::
140_createSingletonInstance(IServiceMng* sm, IServiceInfo* si, const ServiceBuildInfoBase& sbi)
141{
142 ITraceMng* tm = sm->traceMng();
143 IServiceFactoryInfo* sfi = si->factoryInfo();
145
146 // If the singleton factory exists, we use it. Otherwise, we use
147 // the old mechanism. Normally, the singleton factory always exists
148 // unless we are using an Arcane version with an old version of Axlstar.
150 if (ssf) {
151 instance = ssf->createSingletonServiceInstance(sbi);
152 if (instance.get()) {
153 if (!sfi->isSingleton())
154 tm->info() << "WARNING: singleton service loading'"
155 << si->localName() << "' which is not specified as singleton.";
156 }
157 }
158
159 if (instance.get()) {
160 sm->addSingletonInstance(instance);
161 String local_name = si->localName();
162 VersionInfo vi = si->version();
163 StringCollection implemented_interfaces = si->implementedInterfaces();
164 tm->log() << "Loading singleton service " << local_name
165 << " (Version " << vi << ")"
166 << " (Type " << typeid(instance.get()).name() << ")"
167 << " N=" << implemented_interfaces.count();
168 for (StringCollection::Enumerator sc(implemented_interfaces); ++sc;) {
169 tm->log() << " (Interface implemented '" << *sc << "'";
170 }
171 }
172
173 return instance;
174}
175
176/*---------------------------------------------------------------------------*/
177/*---------------------------------------------------------------------------*/
178
180loadSingletonService(ISubDomain* sd, const String& name)
181{
182 // Normally, the service must be a singleton to be loaded
183 // in this manner. Nevertheless, for compatibility reasons, we
184 // allow loading all services in singleton mode and we
185 // display a warning. Eventually, do_all will be false and it will be necessary to specify
186 // that the service is a singleton
187 const bool do_all = true;
188 ITraceMng* trace = sd->traceMng();
189 IServiceMng* service_mng = sd->serviceMng();
190
191 // Checks that no instance of the same name exists.
192 // If so, we do nothing and display a warning.
193 // Maybe a fatal would be more appropriate.
194 SingletonServiceInstanceRef old_instance = service_mng->singletonServiceReference(name);
195 if (old_instance.get()) {
196 trace->warning() << "An instance of singleton service; name: '" << name << "' already exists."
197 << " The second instance will not be created !";
198 return true;
199 }
200
201 ServiceFactory2Collection service_factory_infos(sd->application()->serviceFactories2());
202 for (ServiceFactory2Collection::Enumerator i(service_factory_infos); ++i;) {
204 IServiceInfo* si = sf2->serviceInfo();
205 IServiceFactoryInfo* sfi = si->factoryInfo();
206 if (!do_all)
207 if (!sfi->isSingleton())
208 continue;
209 if (si->localName() != name)
210 continue;
211
212 ServiceBuildInfoBase sbi(sd);
213 auto instance = _createSingletonInstance(service_mng, si, sbi);
214 if (instance.get())
215 return true;
216 }
217 return false;
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
227_loadServices(IApplication* application, const ServiceBuildInfoBase& sbib)
228{
229 // Instantiates singleton services that load automatically
230 // (they have the isAutoload() property set to true).
231 IServiceMng* service_mng = sbib.serviceParent()->serviceMng();
232
233 ServiceFactory2Collection service_factory_infos(application->serviceFactories2());
234 for (ServiceFactory2Collection::Enumerator i(service_factory_infos); ++i;) {
236 IServiceInfo* si = sf2->serviceInfo();
237 IServiceFactoryInfo* sfi = si->factoryInfo();
238 if (!sfi->isSingleton())
239 continue;
240 if (!sfi->isAutoload())
241 continue;
242
243 _createSingletonInstance(service_mng, si, sbib);
244 }
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
251loadModules(ISubDomain* sd, bool all_modules)
252{
253 CriticalSection cs(sd->threadMng());
254
255 ITraceMng* trace = sd->traceMng();
256 IApplication* app = sd->application();
257 ModuleFactoryInfoCollection module_factory_infos(app->moduleFactoryInfos());
258 for (ModuleFactoryInfoCollection::Enumerator i(module_factory_infos); ++i;) {
259 IModuleFactoryInfo* sf = *i;
260 bool is_autoload = sf->isAutoload();
261 if (sf->isAutoload() || all_modules) {
262 Ref<IModule> module = sf->createModule(sd, sd->defaultMeshHandle());
263 if (module.get())
264 trace->info() << "Loading module " << module->name()
265 << " (Version " << module->versionInfo() << ")"
266 << ((is_autoload) ? " (autoload)" : " ");
267 }
268 }
269}
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
276{
277 IApplication* app = sd->application();
278 ModuleFactoryInfoCollection module_factory_infos(app->moduleFactoryInfos());
279 for (ModuleFactoryInfoCollection::Enumerator i(module_factory_infos); ++i;) {
280 IModuleFactoryInfo* sf = *i;
282 }
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288} // End namespace Arcane
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
Critical section in multi-thread.
Application interface.
virtual ModuleFactoryInfoCollection moduleFactoryInfos()=0
List of module factory information.
virtual ServiceFactory2Collection serviceFactories2()=0
List of service factories.
virtual ITraceMng * traceMng() const =0
Trace manager.
virtual IServiceMng * serviceMng() const =0
Service manager.
Information about a module factory.
virtual void initializeModuleFactory(ISubDomain *sub_domain)=0
If the factory is a one-to-one module, initializes it on the sub-domain sub_domain.
virtual Ref< IModule > createModule(ISubDomain *parent, const MeshHandle &mesh_handle)=0
Creates a module.
virtual bool isAutoload() const =0
Indicates if the module should be loaded automatically.
Information about a service factory.
virtual bool isAutoload() const =0
true if the service is a module and must be loaded automatically
virtual bool isSingleton() const =0
true if the service is a singleton service (a single instance)
Interface for service or module information.
virtual String localName() const =0
Local part of the service name.
virtual IServiceFactoryInfo * factoryInfo() const =0
Information on factories available for this service.
virtual VersionInfo version() const =0
Service version.
virtual Internal::ISingletonServiceFactory * singletonFactory() const =0
Factory for singleton services (nullptr if not supported).
virtual StringCollection implementedInterfaces() const =0
List of names of classes implemented by this service.
Service loading interface.
Service manager interface.
Definition IServiceMng.h:32
virtual SingletonServiceInstanceRef singletonServiceReference(const String &name) const =0
virtual ITraceMng * traceMng() const =0
Associated trace manager.
virtual void addSingletonInstance(SingletonServiceInstanceRef sv)=0
Adds a reference to the service sv.
Interface for a case execution session.
Definition ISession.h:38
virtual IApplication * application() const =0
Application.
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual IThreadMng * threadMng()=0
Returns the thread manager.
virtual IApplication * application()=0
Application.
virtual const MeshHandle & defaultMeshHandle()=0
Handle for the default mesh.
virtual TraceMessage warning()=0
Stream for a warning message.
virtual TraceMessage log()=0
Stream for a log message.
virtual TraceMessage info()=0
Stream for an information message.
virtual IServiceInfo * serviceInfo() const =0
Returns the IServiceInfo associated with this factory.
virtual Ref< ISingletonServiceInstance > createSingletonServiceInstance(const ServiceBuildInfoBase &sbi)=0
Create an instance of a singleton service.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
Information for creating a service.
IBase * serviceParent() const
Access to the parent instance that created this instance.
Service loader in the architecture.
void loadApplicationServices(IApplication *) override
Loads available application services.
void _loadServices(IApplication *application, const ServiceBuildInfoBase &sbib)
Loads services in the base manager.
void loadSubDomainServices(ISubDomain *parent) override
Loads available subdomain services in the subdomain sd.
void loadSessionServices(ISession *) override
Loads available session services.
bool loadSingletonService(ISubDomain *sd, const String &name) override
Loads the subdomain singleton service with name name.
void initializeModuleFactories(ISubDomain *sd) override
Calls the initialization methods for module factories.
void loadModules(ISubDomain *sd, bool all_modules) override
Loads available modules.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Collection< String > StringCollection
Collection of strings.
Definition UtilsTypes.h:506
Collection< Internal::IServiceFactory2 * > ServiceFactory2Collection
Collection of service factories.
Ref< ISingletonServiceInstance > SingletonServiceInstanceRef
Reference to the 'ISingletonServiceInstance' interface.
Definition ArcaneTypes.h:91
Collection< IModuleFactoryInfo * > ModuleFactoryInfoCollection
Collection of module factory information.