Arcane  4.1.13.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
FlexLMTools.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* FlexLMTools.cc (C) 2000-2026 */
9/* */
10/* Implémentation d'une interface pour les outils FlexLM. */
11/*---------------------------------------------------------------------------*/
12
13#include "arcane/impl/FlexLMTools.h"
14
15/* L'interface à FlexNet ici employée est une surcouche à FlexNet de TAD
16 * prenant en charge par exemple le rappel périodique du contrôle de licence.
17 * Le recheck par défaut est tous les 120s (cf setCheckInterval)
18 */
19
20#define FLEXLMAPI_IS_STATIC_LIBRARY
21#define c_plusplus
22#include <FlexlmAPI.h>
23
24#include "arcane/IParallelSuperMng.h"
25#include "arcane/utils/FatalErrorException.h"
26#include "arcane/utils/TraceInfo.h"
27#include "arcane/utils/StringBuilder.h"
28#include "arcane/utils/Array.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33ARCANE_BEGIN_NAMESPACE
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38LicenseErrorException::
39LicenseErrorException(const String& where)
40: Exception("LicenseError",where)
41{
42 setCollective(true);
43}
44
45/*---------------------------------------------------------------------------*/
46/*---------------------------------------------------------------------------*/
47
48LicenseErrorException::
49LicenseErrorException(const String& where,const String& message)
50: Exception("LicenseError",where,message)
51{
52 setCollective(true);
53}
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
58LicenseErrorException::
59LicenseErrorException(const TraceInfo& where)
60: Exception("LicenseError",where)
61{
62 setCollective(true);
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68LicenseErrorException::
69LicenseErrorException(const TraceInfo& where,const String& message)
70: Exception("LicenseError",where,message)
71{
72 setCollective(true);
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78void LicenseErrorException::
79explain(std::ostream& m) const
80{
81 m << "Licensing error occured.\n"
82 << "Excution stopped.\n";
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88void LicenseErrorException::
89write(std::ostream& o) const
90{
91 o << name() << "\n";
92#ifdef ARCANE_DEBUG
93 o << "Exception thrown in: '" << where() << "\n";
94#endif /* ARCANE_DEBUG */
95 if (!message().null())
96 o << "Message: " << message() << '\n';
97 this->explain(o);
98#ifdef ARCANE_DEBUG
99 String st = stackTrace().toString();
100 if (!st.null()){
101 o << "\nCall stack:\n";
102 o << st << '\n';
103 }
104#endif /* ARCANE_DEBUG */
105}
106
107/*---------------------------------------------------------------------------*/
108/*---------------------------------------------------------------------------*/
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
113FlexLMMng* FlexLMMng::m_instance = NULL ;
114
115/*---------------------------------------------------------------------------*/
116/*---------------------------------------------------------------------------*/
117
118FlexLMMng::
119FlexLMMng()
120 : m_parallel_super_mng(NULL)
121{
122 ;
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
130instance()
131{
132 if(m_instance==NULL)
133 m_instance = new FlexLMMng() ;
134 return m_instance ;
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140void
142init(IParallelSuperMng * parallel_super_mng)
143{
144 if (m_parallel_super_mng != NULL)
145 throw LicenseErrorException(A_FUNCINFO,"FlexLMMng already initialized");
146
147 // Test en mode master check le droit de décentralisé le contrôle
148 m_is_master = (parallel_super_mng->commRank() == 0);
149
150 // Marque l'initialisation effective; on peut maintenant utiliser le système de licence
151 m_parallel_super_mng = parallel_super_mng;
152}
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
156
157void
160{
161 // Toutes les spécificités sont gérées dans la fonction
162 setcheckinterval(t);
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
168bool
170checkLicense(const String name, const Real version, const bool do_fatal) const
171{
172 if (m_parallel_super_mng == NULL)
173 throw LicenseErrorException(A_FUNCINFO,"FlexLMMng not initialized");
174
175 Integer test = 0;
176 if (m_is_master)
177 test = license_test((char*)name.localstr(),(char*)String::format("{0}",version).localstr());
178 m_parallel_super_mng->broadcast(IntegerArrayView(1,&test),0);
179
180 if (test != 0 && do_fatal)
181 throw LicenseErrorException(A_FUNCINFO,String::format("Checking feature {0} (v{1}) has failed\nFeature info: {2}",name,version,featureInfo(name,version)));
182 return (test == 0);
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
188void
190getLicense(const String name, const Real version, Integer nb_licenses)
191{
192 if (m_parallel_super_mng == NULL)
193 throw LicenseErrorException(A_FUNCINFO,"FlexLMMng not initialized");
194
195 Integer error = 0;
196 if (m_is_master)
197 {
198 m_features[name] += nb_licenses ;
199 for(Integer i=0;i<nb_licenses;++i)
200 error += license_begin_rc((char*)name.localstr(), (char*)String::format("{0}",version).localstr()) ;
201 }
202 m_parallel_super_mng->broadcast(IntegerArrayView(1,&error),0);
203 if (error != 0)
204 throw LicenseErrorException(A_FUNCINFO,String::format("Cannot checkout {0} license{1} for feature {2} (v{3})\nFeature info: {4}",nb_licenses,((nb_licenses>1)?"s":""),name,version,featureInfo(name,version)));
205}
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
210void
212releaseLicense(const String name, Integer nb_licenses)
213{
214 if (m_parallel_super_mng == NULL)
215 throw LicenseErrorException(A_FUNCINFO,"FlexLMMng not initialized");
216
217 if (nb_licenses == 0)
218 return;
219
220 if (m_is_master)
221 {
222 FeatureMapType::iterator finder = m_features.find(name);
223
224 // Pas de code d'erreur pour compatibilité avec la précédente version
225 if (finder == m_features.end()) return;
226
227 Integer & nb_allocated_licenses = finder->second;
228 if (nb_licenses == 0) nb_licenses = nb_allocated_licenses;
229 for(Integer i=0;i<nb_licenses;++i)
230 license_end_no_quit((char*)name.localstr()) ;
231
232 nb_allocated_licenses -= nb_licenses;
233 if (nb_allocated_licenses < 0) nb_allocated_licenses = 0;
234 }
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240void
243{
244 if (m_parallel_super_mng == NULL)
245 return;
246
247 if (m_is_master)
248 {
249 for(FeatureMapType::iterator iter = m_features.begin(); iter!=m_features.end(); ++iter)
250 {
251 const String name = (*iter).first ;
252 Integer nb_licenses = (*iter).second ;
253 for(Integer i=0; i<nb_licenses; ++i)
254 license_end_no_quit((char*) name.localstr()) ;
255 (*iter).second = 0 ;
256 }
257 }
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263String
265featureInfo(const String name, const Real version) const
266{
267 String info;
268 if (m_is_master)
269 {
270 StringBuilder info_builder;
271 if (license_test((char*)name.localstr(),(char*)String::format("{0}",version).localstr()) == 0)
272 {
273 Integer count = 0;
274 char ** users = get_user_list((char*)name.localstr());
275 while(users[count]) { info_builder += String::format("{0} ",users[count++]); }
276 if (count == 0) {
277 info_builder = String::format("no declared user");
278 } else {
279 info_builder = String::format("Used by {0} user{1} : ",count,((count>1)?"s":""),info_builder.toString());
280 }
281
282 // license_test_expiration semble buggué : segfault
283 // int expiration_code = license_test_expiration((char*)name.localstr());
284 // info_builder += String::format("\nExpiration Code {0}",expiration_code);
285
286 info = info_builder.toString();
287 }
288 else
289 {
290 info = "Unknown feature";
291 }
292 }
293
294 // remplace m_parallel_super_mng->broadcastString(info,0) qui n'existe pas dans IParallelSuperMng
295 Integer len_info[1] = { info.utf8().size() };
296 m_parallel_super_mng->broadcast(IntegerArrayView(1,len_info),0);
297 if (m_is_master) {
298 ByteUniqueArray utf8_array(info.utf8());
299 m_parallel_super_mng->broadcast(utf8_array,0);
300 } else {
301 ByteUniqueArray utf8_array(len_info[0]);
302 m_parallel_super_mng->broadcast(utf8_array,0);
303 info = String::fromUtf8(utf8_array);
304 }
305
306 return info;
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
312ARCANE_END_NAMESPACE
313
314/*---------------------------------------------------------------------------*/
315/*---------------------------------------------------------------------------*/
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
FlexLM manager.
Definition FlexLMTools.h:72
static FlexLMMng * instance()
Accès au singleton.
FlexLMMng()
Constructeur.
void getLicense(const String name, const Real version, Integer nb_licenses=1)
Demande l'allocation de.
bool checkLicense(const String name, const Real version, bool do_fatal=true) const
Teste la présence d'une fonctionnalité statique.
void setCheckInterval(const Integer t=120)
Définit une nouvelle périodicité du contrôle des licences.
void init(IParallelSuperMng *parallel_super_mng)
Initialise le gestionnaire de licences.
void releaseAllLicenses()
Relache toutes les licences allouées.
bool m_is_master
Cet host est il le maître des contrôles ?
void releaseLicense(const String name, Integer nb_licenses=0)
Relache les licences de la fonctionnalité
String featureInfo(const String name, const Real version) const
Return info on feature.
Classe abstraite du superviseur de parallélisme.
virtual Int32 commRank() const =0
Retourne le numéro du process (compris entre 0 et nbProcess()-1).
Exception de licence.
Definition FlexLMTools.h:42
Constructeur de chaîne de caractère unicode.
String toString() const
Retourne la chaîne de caractères construite.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:305
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:228
ByteConstArrayView utf8() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:276
Int32 Integer
Type représentant un entier.
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:457
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:335
double Real
Type représentant un réel.