Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ServiceLoader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* Chargeur des services disponibles dans le 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/IServiceLoader.h"
22#include "arcane/IServiceMng.h"
23#include "arcane/ISubDomain.h"
24#include "arcane/Service.h"
25#include "arcane/IModuleFactory.h"
26#include "arcane/IModule.h"
27
28#include "arcane/ServiceInfo.h"
29#include "arcane/IService.h"
30
31#include <typeinfo>
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
45: public IServiceLoader
46{
47 public:
48
49 public:
50
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
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 // Si la fabrique singleton existe, on l'utilise. Sinon, on utilise
147 // l'ancien mécanisme. Normalement, la fabrique singleton existe toujours
148 // sauf si on utilise une version de Arcane avec une vieille version de Axlstar.
149 Internal::ISingletonServiceFactory* ssf = si->singletonFactory();
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
181{
182 // Normalement, le service doit être singleton pour pouvoir être chargé
183 // de cette maniére. Néanmoins, pour des raisons de compatibilité, on
184 // autorise le chargement en mode singleton de tous les services et on
185 // affiche un avertissement. A terme, do_all sera faux et il faudra spécifier
186 // que le service est singleton
187 const bool do_all = true;
188 ITraceMng* trace = sd->traceMng();
189 IServiceMng* service_mng = sd->serviceMng();
190
191 // Vérifie qu'aucune instance de même nom n'existe.
192 // Si c'est le cas, on ne fait rien et on affiche un avertissement.
193 // Peut-être un fatal serait plus approprié.
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
213 auto instance = _createSingletonInstance(service_mng,si,sbi);
214 if (instance.get())
215 return true;
216 }
217 return false;
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
227{
228 // Instantie les services singletons qui se chargent automatiquement
229 // (ils ont la propriété isAutoload() à vrai).
230 IServiceMng* service_mng = sbib.serviceParent()->serviceMng();
231
232 ServiceFactory2Collection service_factory_infos(application->serviceFactories2());
233 for( ServiceFactory2Collection::Enumerator i(service_factory_infos); ++i; ){
235 IServiceInfo* si = sf2->serviceInfo();
236 IServiceFactoryInfo* sfi = si->factoryInfo();
237 if (!sfi->isSingleton())
238 continue;
239 if (!sfi->isAutoload())
240 continue;
241
242 _createSingletonInstance(service_mng,si,sbib);
243 }
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
251{
252 CriticalSection cs(sd->threadMng());
253
254 ITraceMng* trace = sd->traceMng();
255 IApplication* app = sd->application();
259 bool is_autoload = sf->isAutoload();
260 if (sf->isAutoload() || all_modules){
261 Ref<IModule> module = sf->createModule(sd,sd->defaultMeshHandle());
262 if (module.get())
263 trace->info() << "Loading module " << module->name()
264 << " (Version " << module->versionInfo() << ")"
265 << ((is_autoload) ? " (autoload)" : " ");
266 }
267 }
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
275{
276 IApplication* app = sd->application();
280 sf->initializeModuleFactory(sd);
281 }
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
287} // End namespace Arcane
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
EnumeratorT< String > Enumerator
Type d'un itérateur sur toute la collection.
Definition Collection.h:129
Section critique en multi-thread.
Interface de l'application.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
Informations sur la fabrique d'un module.
Informations sur la fabrique d'un service.
Interface des informations d'un service ou d'un module.
virtual String localName() const =0
Partie locale du nom du service.
virtual VersionInfo version() const =0
Version du service.
virtual StringCollection implementedInterfaces() const =0
Liste des noms des classes implémentées par ce service.
Interface de chargement des services.
Interface du gestionnaire de services.
Definition IServiceMng.h:31
virtual void addSingletonInstance(SingletonServiceInstanceRef sv)=0
Ajoute une référence au service sv.
Interface d'une session d'exécution d'un cas.
Definition ISession.h:44
virtual IApplication * application() const =0
Application.
Interface du gestionnaire d'un sous-domaine.
Definition ISubDomain.h:74
virtual IApplication * application()=0
Application.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Informations pour créer un service.
Chargeur des services dans l'architecture.
void loadApplicationServices(IApplication *) override
Charge les services applicatifs disponibles.
void _loadServices(IApplication *application, const ServiceBuildInfoBase &sbib)
Charge les services dans le gestionnaire base.
void loadSubDomainServices(ISubDomain *parent) override
Charge les services de sous-domaine disponibles dans le sous-domaine sd.
void loadSessionServices(ISession *) override
Charge les services de session disponibles.
bool loadSingletonService(ISubDomain *sd, const String &name) override
Charge le service singleton de sous-domaine de nom name.
void initializeModuleFactories(ISubDomain *sd) override
Appel les méthodes d'initialisation des fabriques des modules.
void loadModules(ISubDomain *sd, bool all_modules) override
Charge les modules disponibles.
Interface du gestionnaire de traces.
virtual TraceMessage warning()=0
Flot pour un message d'avertissement.
virtual TraceMessage info()=0
Flot pour un message d'information.
virtual TraceMessage log()=0
Flot pour un message de log.
Référence à une instance.
InstanceType * get() const
Instance associée ou nullptr si aucune.
Chaîne de caractères unicode.
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage info() const
Flot pour un message d'information.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Collection< String > StringCollection
Collection de chaînes de caractères.
Definition UtilsTypes.h:664