Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ServiceAndModuleFactoryMng.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/* ServiceAndModuleFactoryMng.cc (C) 2000-2019 */
9/* */
10/* Gestionnaire des fabriques de services et modules. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/ReferenceCounter.h"
15
16#include "arcane/utils/TraceAccessor.h"
17#include "arcane/utils/List.h"
18#include "arcane/utils/OStringStream.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/VersionInfo.h"
21#include "arcane/utils/ITraceMng.h"
22#include "arcane/utils/Array.h"
23
24#include "arcane/ServiceUtils.h"
25#include "arcane/ServiceInfo.h"
26#include "arcane/ServiceRegisterer.h"
27#include "arcane/IServiceFactory.h"
28#include "arcane/IModuleFactory.h"
29#include "arcane/ModuleProperty.h"
30#include "arcane/IServiceAndModuleFactoryMng.h"
31
32#include <set>
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37ARCANE_BEGIN_NAMESPACE
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
47class ARCANE_IMPL_EXPORT ServiceAndModuleFactoryMng
48: public TraceAccessor
50{
51 public:
52
53 class Impl;
54
55 public:
56
59
60 public:
61
63
67
70
71 private:
72
73 std::set<ServiceRegisterer*> m_service_registerer_done_set;
74 Impl* m_p;
75
76 private:
77
78 void _addFactoryFromServiceRegisterer(ServiceRegisterer* sr);
79};
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
85{
86 public:
87
88 ServiceFactoryInfoCollection serviceFactoryInfos() const { return m_service_factory_infos; }
89 ServiceFactory2Collection serviceFactories2() const { return m_service_factories2; }
90 ModuleFactoryInfoCollection moduleFactoryInfos() const { return m_module_factory_infos; }
91
92 public:
93
94 ~Impl()
95 {
96 // Il ne faut pas détruire les instances de IServiceFactory2 car elle
97 // sont gérées par le IServiceInfo correspondant.
98
99 for( List<IServiceInfo*>::Enumerator i(m_service_infos); ++i; )
100 delete *i;
101
102 for( IServiceFactoryInfo* sfi : m_deletable_service_factory_list )
103 delete sfi;
104 }
105
106 void addServiceFactory(IServiceFactoryInfo* sfi,bool need_delete)
107 {
108 if (m_service_factory_set.find(sfi)!=m_service_factory_set.end()){
109 std::cout << "Service Factory is already referenced\n";
110 return;
111 }
112 m_service_factory_set.insert(sfi);
113 m_service_factory_infos.add(sfi);
114 if (need_delete)
115 m_deletable_service_factory_list.add(sfi);
116 IServiceInfo* si = sfi->serviceInfo();
117 for( ServiceFactory2Collection::Enumerator j(si->factories()); ++j; ){
119 m_service_factories2.add(sf2);
120 }
121 }
122
123 void addModuleFactory(IModuleFactoryInfo* mfi)
124 {
125 if (m_module_factory_set.find(mfi)!=m_module_factory_set.end()){
126 std::cout << "Module Factory is already referenced\n";
127 return;
128 }
129 m_module_factory_set.insert(mfi);
130 m_module_factory_infos.add(mfi);
131 m_deletable_module_factory_list.add(ModuleFactoryReference(mfi));
132 }
133
134 void registerServiceInfoForDelete(IServiceInfo* si)
135 {
136 m_service_infos.add(si);
137 }
138
139 private:
140
149
154
155 std::set<IServiceFactoryInfo*> m_service_factory_set;
156 std::set<IModuleFactoryInfo*> m_module_factory_set;
157};
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
162extern "C++" ARCANE_IMPL_EXPORT IServiceAndModuleFactoryMng*
163arcaneCreateServiceAndModuleFactoryMng(ITraceMng* tm)
164{
166 return sm;
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
172ServiceAndModuleFactoryMng::
173ServiceAndModuleFactoryMng(ITraceMng* tm)
175, m_p(new Impl())
176{
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
191
192/*---------------------------------------------------------------------------*/
193/*---------------------------------------------------------------------------*/
194
197{
198 return m_p->serviceFactoryInfos();
199}
200
201/*---------------------------------------------------------------------------*/
202/*---------------------------------------------------------------------------*/
203
205serviceFactories2() const
206{
207 return m_p->serviceFactories2();
208}
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
214moduleFactoryInfos() const
215{
216 return m_p->moduleFactoryInfos();
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
224{
225 // Les fabriques globales ne doivent pas être détruites par nous.
226 info() << "Add global service factory name=" << sfi->serviceInfo()->localName();
227 m_p->addServiceFactory(sfi,false);
228}
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
235{
236 // Les fabriques globales ne doivent pas être détruites par nous.
237 info() << "Add global module factory name=" << mfi->moduleName();
238 m_p->addModuleFactory(mfi);
239}
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
246{
248 if (!sr)
249 log() << "WARNING: No registered service";
250
252 std::set<ServiceRegisterer*> registered_services;
253
254 // Enregistre toutes les fabriques utilisant ServiceRegisterer
255
256 while(sr){
257 // Detecte les problèmes de boucle infinie (eg: si deux services ont le même nom)
258 // Désormais les contrôles dans ServiceRegisterer devrait toutefois suffire
259 if (registered_services.find(sr) == registered_services.end()) {
260 oss() << "\t" << sr->name() << '\n';
261 registered_services.insert(sr);
262 }
263 else {
264 cout << "=== Registered service factories ===\n"
265 << " Registered service count: " << registered_services.size() << " / " << ServiceRegisterer::nbService()
266 << "====================================\n"
267 << oss.str()
268 << "====================================" << endl;
269 ARCANE_FATAL("Infinite loop in service registration");
270 }
271
273
274 sr = sr->nextService();
275 }
276}
277
278/*---------------------------------------------------------------------------*/
279/*---------------------------------------------------------------------------*/
289{
290 ARCANE_CHECK_POINTER2(sr,"ServiceRegisterer");
291
292 bool is_ok = false;
293
294 // Regarde si \a sr n'a pas déjà été traité.
295 // Cela peut arriver avec le chargement dynamique si createAllServiceRegistererFactories()
296 // est appelé plusieurs fois.
297 if (m_service_registerer_done_set.find(sr)!=m_service_registerer_done_set.end())
298 return;
299 m_service_registerer_done_set.insert(sr);
300
301 // Tente de créer le IServiceInfo suivant les différentes méthodes possibles.
302 // Si sr->moduleFactoryWithPropertyFunction() est non nul, il s'agit d'une fabrique de module.
303 // Sinon, il s'agit obligatoirement d'un service.
304 if (sr->moduleFactoryWithPropertyFunction()){
305 IModuleFactoryInfo* mfi = (*sr->moduleFactoryWithPropertyFunction())(sr->moduleProperty());
306 if (mfi){
307 m_p->addModuleFactory(mfi);
308 //trace->info() << "Add module factory for '" << si->localName() << "' mfi=" << mfi;
309 is_ok = true;
310 }
311 }
312 else{
313 auto property_info_func = sr->infoCreatorWithPropertyFunction();
315 ARCANE_FATAL("Null PropertyFunc for ServiceRegisterer");
316
317 IServiceInfo* si = (*property_info_func)(sr->serviceProperty());
318 if (!si)
319 ARCANE_FATAL("Null ServiceInfo created by ServiceRegisterer");
320
321 // Indique qu'il faudra détruire l'instance \a si
322 m_p->registerServiceInfoForDelete(si);
323
324 IServiceFactoryInfo* sfi = si->factoryInfo();
325
326 if (sfi){
327 m_p->addServiceFactory(sfi,true);
328 //trace->info() << "Add service factory for '" << si->localName() << "' sfi=" << sfi;
329 is_ok = true;
330 }
331 }
332
333 if (!is_ok){
334 info() << "WARNING: ServiceRegisterer does not have a valid create function name=" << sr->name();
335 }
336}
337
338/*---------------------------------------------------------------------------*/
339/*---------------------------------------------------------------------------*/
340
341ARCANE_END_NAMESPACE
342
343/*---------------------------------------------------------------------------*/
344/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER2(ptr, text)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Informations sur la fabrique d'un module.
Interface d'un gestionnaire de fabriques de services et modules.
virtual ServiceFactoryInfoCollection serviceFactoryInfos() const =0
Liste des informations sur les fabriques des services.
virtual ModuleFactoryInfoCollection moduleFactoryInfos() const =0
Liste des fabriques de service.
virtual void createAllServiceRegistererFactories()=0
Créé toutes les fabriques associées à des ServiceRegisterer.
virtual ServiceFactory2Collection serviceFactories2() const =0
Liste des informations sur les fabriques des modules.
virtual void addGlobalFactory(IServiceFactoryInfo *sfi)=0
Ajoute la fabrique de service sfi. sfi ne doit pas être détruit tant que cette instance est utilisée....
Informations sur la fabrique d'un service.
Interface des informations d'un service ou d'un module.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Compteur de référence sur une fabrique de module.
Flot de sortie lié à une String.
List< IServiceFactoryInfo * > m_service_factory_infos
Liste des informations sur les fabriques des services.
UniqueArray< IServiceFactoryInfo * > m_deletable_service_factory_list
Liste des IServiceFactoryInfo à détruire.
List< IModuleFactoryInfo * > m_module_factory_infos
Liste des informations sur les fabriques des modules.
UniqueArray< ModuleFactoryReference > m_deletable_module_factory_list
Liste des IModuleFactoryInfo à détruire.
List< Internal::IServiceFactory2 * > m_service_factories2
Liste des informations sur les fabriques des services (V2)
List< IServiceInfo * > m_service_infos
Liste des informations sur les des services.
Gestionnaire des fabriques de services et modules.
virtual ServiceFactoryInfoCollection serviceFactoryInfos() const
Liste des informations sur les fabriques des services.
void _addFactoryFromServiceRegisterer(ServiceRegisterer *sr)
Ajoute la fabrique spécifiée par sr.
virtual void addGlobalFactory(IServiceFactoryInfo *sfi)
Ajoute la fabrique de service sfi. sfi ne doit pas être détruit tant que cette instance est utilisée....
virtual ~ServiceAndModuleFactoryMng()
Détruit le gestionnaire.
virtual ModuleFactoryInfoCollection moduleFactoryInfos() const
Liste des fabriques de service.
virtual void createAllServiceRegistererFactories()
Créé toutes les fabriques associées à des ServiceRegisterer.
virtual ServiceFactory2Collection serviceFactories2() const
Liste des informations sur les fabriques des modules.
Enregistreur de service et modules.
static ServiceRegisterer * firstService()
Accès au premier élément de la chaine d'enregistreur de service.
static Integer nbService()
Nombre d'enregisteur de service dans la chaine.
Interface du gestionnaire de traces.
TraceMessage log() const
Flot pour un message de log.
TraceMessage info() const
Flot pour un message d'information.