Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ServiceAndModuleFactoryMng.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/* ServiceAndModuleFactoryMng.cc (C) 2000-2019 */
9/* */
10/* Manager of service and module factories. */
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/core/ServiceUtils.h"
25#include "arcane/core/ServiceInfo.h"
26#include "arcane/core/ServiceRegisterer.h"
27#include "arcane/core/IServiceFactory.h"
28#include "arcane/core/IModuleFactory.h"
29#include "arcane/core/ModuleProperty.h"
30#include "arcane/core/IServiceAndModuleFactoryMng.h"
31
32#include <set>
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
46class ARCANE_IMPL_EXPORT ServiceAndModuleFactoryMng
47: public TraceAccessor
49{
50 public:
51
52 class Impl;
53
54 public:
55
56 ServiceAndModuleFactoryMng(ITraceMng* tm);
57 virtual ~ServiceAndModuleFactoryMng();
58
59 public:
60
62
66
67 virtual void addGlobalFactory(IServiceFactoryInfo* sfi);
68 virtual void addGlobalFactory(IModuleFactoryInfo* mfi);
69
70 private:
71
72 std::set<ServiceRegisterer*> m_service_registerer_done_set;
73 Impl* m_p;
74
75 private:
76
78};
79
80/*---------------------------------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
84{
85 public:
86
90
91 public:
92
93 ~Impl()
94 {
95 // The instances of IServiceFactory2 must not be destroyed because they
96 // are managed by the corresponding IServiceInfo.
97
99 delete *i;
100
102 delete sfi;
103 }
104
105 void addServiceFactory(IServiceFactoryInfo* sfi, bool need_delete)
106 {
107 if (m_service_factory_set.find(sfi) != m_service_factory_set.end()) {
108 std::cout << "Service Factory is already referenced\n";
109 return;
110 }
111 m_service_factory_set.insert(sfi);
113 if (need_delete)
115 IServiceInfo* si = sfi->serviceInfo();
118 m_service_factories2.add(sf2);
119 }
120 }
121
122 void addModuleFactory(IModuleFactoryInfo* mfi)
123 {
124 if (m_module_factory_set.find(mfi) != m_module_factory_set.end()) {
125 std::cout << "Module Factory is already referenced\n";
126 return;
127 }
128 m_module_factory_set.insert(mfi);
129 m_module_factory_infos.add(mfi);
131 }
132
133 void registerServiceInfoForDelete(IServiceInfo* si)
134 {
135 m_service_infos.add(si);
136 }
137
138 private:
139
148
153
154 std::set<IServiceFactoryInfo*> m_service_factory_set;
155 std::set<IModuleFactoryInfo*> m_module_factory_set;
156};
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161extern "C++" ARCANE_IMPL_EXPORT IServiceAndModuleFactoryMng*
162arcaneCreateServiceAndModuleFactoryMng(ITraceMng* tm)
163{
164 IServiceAndModuleFactoryMng* sm = new ServiceAndModuleFactoryMng(tm);
165 return sm;
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
171ServiceAndModuleFactoryMng::
172ServiceAndModuleFactoryMng(ITraceMng* tm)
173: TraceAccessor(tm)
174, m_p(new Impl())
175{
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 // Global factories must not be destroyed by us.
226 info() << "Add global service factory name=" << sfi->serviceInfo()->localName();
227 m_p->addServiceFactory(sfi, false);
228}
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
235{
236 // Global factories must not be destroyed by us.
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
251 OStringStream oss;
252 std::set<ServiceRegisterer*> registered_services;
253
254 // Registers all factories using ServiceRegisterer
255
256 while (sr) {
257 // Detects infinite loop problems (e.g., if two services have the same name)
258 // Controls in ServiceRegisterer should now be sufficient.
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/*---------------------------------------------------------------------------*/
280
290{
291 ARCANE_CHECK_POINTER2(sr, "ServiceRegisterer");
292
293 bool is_ok = false;
294
295 // Checks if \a sr has already been processed.
296 // This can happen with dynamic loading if createAllServiceRegistererFactories()
297 // is called multiple times.
298 if (m_service_registerer_done_set.find(sr) != m_service_registerer_done_set.end())
299 return;
300 m_service_registerer_done_set.insert(sr);
301
302 // Tries to create the IServiceInfo using the different possible methods.
303 // If sr->moduleFactoryWithPropertyFunction() is not null, it is a module factory.
304 // Otherwise, it must be a service.
307 if (mfi) {
308 m_p->addModuleFactory(mfi);
309 //trace->info() << "Add module factory for '" << si->localName() << "' mfi=" << mfi;
310 is_ok = true;
311 }
312 }
313 else {
314 auto property_info_func = sr->infoCreatorWithPropertyFunction();
315 if (!property_info_func)
316 ARCANE_FATAL("Null PropertyFunc for ServiceRegisterer");
317
318 IServiceInfo* si = (*property_info_func)(sr->serviceProperty());
319 if (!si)
320 ARCANE_FATAL("Null ServiceInfo created by ServiceRegisterer");
321
322 // Indicates that the instance \a si must be destroyed.
323 m_p->registerServiceInfoForDelete(si);
324
325 IServiceFactoryInfo* sfi = si->factoryInfo();
326
327 if (sfi) {
328 m_p->addServiceFactory(sfi, true);
329 //trace->info() << "Add service factory for '" << si->localName() << "' sfi=" << sfi;
330 is_ok = true;
331 }
332 }
333
334 if (!is_ok) {
335 info() << "WARNING: ServiceRegisterer does not have a valid create function name=" << sr->name();
336 }
337}
338
339/*---------------------------------------------------------------------------*/
340/*---------------------------------------------------------------------------*/
341
342} // namespace Arcane
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER2(ptr, text)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Information about a module factory.
virtual String moduleName() const =0
Name of the module created by this factory.
Interface of a service and module factory manager.
Information about a service factory.
virtual IServiceInfo * serviceInfo() const =0
Information about the service that can be created by this factory.
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 ServiceFactory2Collection factories() const =0
List of service factories.
Implementation of a collection of elements in vector form.
ListEnumeratorT< T > Enumerator
Type of a constant iterator over the entire array.
Reference counter for a module factory.
Output stream linked to a String.
List< IServiceFactoryInfo * > m_service_factory_infos
List of service factory information.
UniqueArray< IServiceFactoryInfo * > m_deletable_service_factory_list
List of IServiceFactoryInfo to be destroyed.
List< IModuleFactoryInfo * > m_module_factory_infos
List of module factory information.
UniqueArray< ModuleFactoryReference > m_deletable_module_factory_list
List of IModuleFactoryInfo to be destroyed.
List< Internal::IServiceFactory2 * > m_service_factories2
List of service factory information (V2).
List< IServiceInfo * > m_service_infos
List of service information.
virtual ServiceFactoryInfoCollection serviceFactoryInfos() const
List of information about service factories.
void _addFactoryFromServiceRegisterer(ServiceRegisterer *sr)
Adds the factory specified by sr.
virtual void addGlobalFactory(IServiceFactoryInfo *sfi)
Adds the service factory sfi. sfi must not be destroyed while this instance is in use....
virtual ~ServiceAndModuleFactoryMng()
Destroys the manager.
virtual ModuleFactoryInfoCollection moduleFactoryInfos() const
List of service factories.
virtual void createAllServiceRegistererFactories()
Creates all factories associated with a ServiceRegisterer.
virtual ServiceFactory2Collection serviceFactories2() const
List of information about module factories.
Service and module registrar.
static ServiceRegisterer * firstService()
Access to the first element of the service registrar chain.
ServiceRegisterer * nextService() const
Next service (0 if the last).
const ServiceProperty & serviceProperty() const
Properties in the case of a service.
const char * name()
Service name.
ModuleFactoryWithPropertyFunc moduleFactoryWithPropertyFunction()
Creation function for the factory if it is a module.
ServiceInfoWithPropertyCreateFunc infoCreatorWithPropertyFunction()
Creation function for the 'ServiceInfo' instance if it is a service.
static Integer nbService()
Number of service registrars in the chain.
const ModuleProperty & moduleProperty() const
Properties in the case of a module.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage log() const
Flow for a log message.
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Collection< IServiceFactoryInfo * > ServiceFactoryInfoCollection
Collection of service factory information.
Collection< Internal::IServiceFactory2 * > ServiceFactory2Collection
Collection of service factories.
Collection< IModuleFactoryInfo * > ModuleFactoryInfoCollection
Collection of module factory information.