Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
FlexLMTools.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/* FlexLMTools.cc (C) 2000-2026 */
9/* */
10/* Implementation of an interface for FlexLM tools. */
11/*---------------------------------------------------------------------------*/
12
13#include "arcane/impl/FlexLMTools.h"
14
15/* The FlexNet interface used here is a TAD overlay on FlexNet
16 * supporting, for example, periodic license check reminders.
17 * The default recheck is every 120s (see setCheckInterval)
18 */
19
20#define FLEXLMAPI_IS_STATIC_LIBRARY
21#define c_plusplus
22#include <FlexlmAPI.h>
23
24#include "arcane/core/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
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39LicenseErrorException::
40LicenseErrorException(const String& where)
41: Exception("LicenseError", where)
42{
43 setCollective(true);
44}
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49LicenseErrorException::
50LicenseErrorException(const String& where, const String& message)
51: Exception("LicenseError", where, message)
52{
53 setCollective(true);
54}
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59LicenseErrorException::
60LicenseErrorException(const TraceInfo& where)
61: Exception("LicenseError", where)
62{
63 setCollective(true);
64}
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69LicenseErrorException::
70LicenseErrorException(const TraceInfo& where, const String& message)
71: Exception("LicenseError", where, message)
72{
73 setCollective(true);
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79void LicenseErrorException::
80explain(std::ostream& m) const
81{
82 m << "Licensing error occured.\n"
83 << "Excution stopped.\n";
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89void LicenseErrorException::
90write(std::ostream& o) const
91{
92 o << name() << "\n";
93#ifdef ARCANE_DEBUG
94 o << "Exception thrown in: '" << where() << "\n";
95#endif /* ARCANE_DEBUG */
96 if (!message().null())
97 o << "Message: " << message() << '\n';
98 this->explain(o);
99#ifdef ARCANE_DEBUG
100 String st = stackTrace().toString();
101 if (!st.null()) {
102 o << "\nCall stack:\n";
103 o << st << '\n';
104 }
105#endif /* ARCANE_DEBUG */
106}
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114FlexLMMng* FlexLMMng::m_instance = NULL;
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
119FlexLMMng::
120FlexLMMng()
121: m_parallel_super_mng(NULL)
122{
123 ;
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
131instance()
132{
133 if (m_instance == NULL)
134 m_instance = new FlexLMMng();
135 return m_instance;
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
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
159{
160 // Toutes les spécificités sont gérées dans la fonction
161 setcheckinterval(t);
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
168checkLicense(const String name, const Real version, const bool do_fatal) const
169{
170 if (m_parallel_super_mng == NULL)
171 throw LicenseErrorException(A_FUNCINFO, "FlexLMMng not initialized");
172
173 Integer test = 0;
174 if (m_is_master)
175 test = license_test((char*)name.localstr(), (char*)String::format("{0}", version).localstr());
176 m_parallel_super_mng->broadcast(IntegerArrayView(1, &test), 0);
177
178 if (test != 0 && do_fatal)
179 throw LicenseErrorException(A_FUNCINFO, String::format("Checking feature {0} (v{1}) has failed\nFeature info: {2}", name, version, featureInfo(name, version)));
180 return (test == 0);
181}
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
187getLicense(const String name, const Real version, Integer nb_licenses)
188{
189 if (m_parallel_super_mng == NULL)
190 throw LicenseErrorException(A_FUNCINFO, "FlexLMMng not initialized");
191
192 Integer error = 0;
193 if (m_is_master) {
194 m_features[name] += nb_licenses;
195 for (Integer i = 0; i < nb_licenses; ++i)
196 error += license_begin_rc((char*)name.localstr(), (char*)String::format("{0}", version).localstr());
197 }
198 m_parallel_super_mng->broadcast(IntegerArrayView(1, &error), 0);
199 if (error != 0)
200 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)));
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
207releaseLicense(const String name, Integer nb_licenses)
208{
209 if (m_parallel_super_mng == NULL)
210 throw LicenseErrorException(A_FUNCINFO, "FlexLMMng not initialized");
211
212 if (nb_licenses == 0)
213 return;
214
215 if (m_is_master) {
216 FeatureMapType::iterator finder = m_features.find(name);
217
218 // Pas de code d'erreur pour compatibilité avec la précédente version
219 if (finder == m_features.end())
220 return;
221
222 Integer& nb_allocated_licenses = finder->second;
223 if (nb_licenses == 0)
224 nb_licenses = nb_allocated_licenses;
225 for (Integer i = 0; i < nb_licenses; ++i)
226 license_end_no_quit((char*)name.localstr());
227
228 nb_allocated_licenses -= nb_licenses;
229 if (nb_allocated_licenses < 0)
230 nb_allocated_licenses = 0;
231 }
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
239{
240 if (m_parallel_super_mng == NULL)
241 return;
242
243 if (m_is_master) {
244 for (FeatureMapType::iterator iter = m_features.begin(); iter != m_features.end(); ++iter) {
245 const String name = (*iter).first;
246 Integer nb_licenses = (*iter).second;
247 for (Integer i = 0; i < nb_licenses; ++i)
248 license_end_no_quit((char*)name.localstr());
249 (*iter).second = 0;
250 }
251 }
252}
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
256
257String
259featureInfo(const String name, const Real version) const
260{
261 String info;
262 if (m_is_master) {
263 StringBuilder info_builder;
264 if (license_test((char*)name.localstr(), (char*)String::format("{0}", version).localstr()) == 0) {
265 Integer count = 0;
266 char** users = get_user_list((char*)name.localstr());
267 while (users[count]) {
268 info_builder += String::format("{0} ", users[count++]);
269 }
270 if (count == 0) {
271 info_builder = String::format("no declared user");
272 }
273 else {
274 info_builder = String::format("Used by {0} user{1} : ", count, ((count > 1) ? "s" : ""), info_builder.toString());
275 }
276
277 // license_test_expiration semble buggué : segfault
278 // int expiration_code = license_test_expiration((char*)name.localstr());
279 // info_builder += String::format("\nExpiration Code {0}",expiration_code);
280
281 info = info_builder.toString();
282 }
283 else {
284 info = "Unknown feature";
285 }
286 }
287
288 // remplace m_parallel_super_mng->broadcastString(info,0) qui n'existe pas dans IParallelSuperMng
289 Integer len_info[1] = { info.utf8().size() };
290 m_parallel_super_mng->broadcast(IntegerArrayView(1, len_info), 0);
291 if (m_is_master) {
292 ByteUniqueArray utf8_array(info.utf8());
293 m_parallel_super_mng->broadcast(utf8_array, 0);
294 }
295 else {
296 ByteUniqueArray utf8_array(len_info[0]);
297 m_parallel_super_mng->broadcast(utf8_array, 0);
298 info = String::fromUtf8(utf8_array);
299 }
300
301 return info;
302}
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
307} // namespace Arcane
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
constexpr Integer size() const noexcept
Number of elements in the array.
FlexLM manager.
Definition FlexLMTools.h:74
static FlexLMMng * instance()
Access to the singleton.
FlexLMMng()
Constructor.
void getLicense(const String name, const Real version, Integer nb_licenses=1)
Requests the allocation of.
bool checkLicense(const String name, const Real version, bool do_fatal=true) const
Tests the presence of a static feature.
void setCheckInterval(const Integer t=120)
Sets a new license check periodicity.
void init(IParallelSuperMng *parallel_super_mng)
Initializes the license manager.
void releaseAllLicenses()
Releases all allocated licenses.
bool m_is_master
Is this host the master for checks?
void releaseLicense(const String name, Integer nb_licenses=0)
Releases the licenses for the feature.
String featureInfo(const String name, const Real version) const
Return info on feature.
Abstract class of the parallelism supervisor.
virtual Int32 commRank() const =0
Returns the process number (between 0 and nbProcess()-1).
Unicode character string constructor.
String toString() const
Returns the constructed character string.
bool null() const
Returns true if the string is null.
Definition String.cc:306
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
ByteConstArrayView utf8() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:277
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
ArrayView< Integer > IntegerArrayView
C equivalent of a 1D array of integers.
Definition UtilsTypes.h:457
UniqueArray< Byte > ByteUniqueArray
Dynamic 1D array of characters.
Definition UtilsTypes.h:335
double Real
Type representing a real number.