dlLibraryTable.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2018-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "dlLibraryTable.H"
30 #include "OSspecific.H"
31 #include "IOstreams.H"
32 #include "int.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(dlLibraryTable, 0);
39 }
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
44 void* Foam::dlLibraryTable::openLibrary
45 (
46  const fileName& libName,
47  bool verbose
48 )
49 {
50  if (libName.empty())
51  {
52  return nullptr;
53  }
54 
55  std::string msg;
56  void* ptr = Foam::dlOpen(fileName(libName).expand(), msg);
57 
59  << "Opened " << libName
60  << " resulting in handle " << Foam::name(ptr) << nl;
61 
62  if (!ptr)
63  {
64  // Even with details turned off, we want some feedback about failure
65  OSstream& os = (verbose ? WarningInFunction : Serr);
66  os << "Could not load " << libName << nl << msg.c_str() << endl;
67  }
68 
69  return ptr;
70 }
71 
72 
73 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
74 
76 (
77  const UList<fileName>& libNames,
78  bool verbose
79 )
80 {
81  dlLibraryTable::open(libNames, verbose);
82 }
83 
84 
86 (
87  const dictionary& dict,
88  const word& libsEntry
89 )
90 {
91  dlLibraryTable::open(dict, libsEntry);
92 }
93 
94 
95 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
96 
98 {
99  clear();
100 }
101 
102 
103 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
104 
106 {
107  for (const void* ptr : libPtrs_)
108  {
109  if (ptr != nullptr)
110  {
111  return false;
112  }
113  }
114 
115  return true;
116 }
117 
118 
119 Foam::label Foam::dlLibraryTable::size() const
120 {
121  label nLoaded = 0;
122 
123  for (const void* ptr : libPtrs_)
124  {
125  if (ptr != nullptr)
126  {
127  ++nLoaded;
128  }
129  }
130 
131  return nLoaded;
132 }
133 
134 
135 void Foam::dlLibraryTable::clear(bool verbose)
136 {
137  label nLoaded = 0;
138 
139  forAllReverse(libPtrs_, i)
140  {
141  void* ptr = libPtrs_[i];
142 
143  if (ptr == nullptr)
144  {
145  libNames_[i].clear();
146  continue;
147  }
148 
149  if (Foam::dlClose(ptr))
150  {
152  << "Closed [" << i << "] " << libNames_[i]
153  << " with handle " << Foam::name(ptr) << nl;
154 
155  libPtrs_[i] = nullptr;
156  libNames_[i].clear();
157  }
158  else
159  {
160  ++nLoaded; // Still loaded
161 
162  if (verbose)
163  {
165  << "Failed closing " << libNames_[i]
166  << " with handle " << Foam::name(ptr) << endl;
167  }
168  }
169  }
170 
171 
172  // Compact the lists
173  if (nLoaded && nLoaded != libPtrs_.size())
174  {
175  nLoaded = 0;
176 
177  forAll(libPtrs_, i)
178  {
179  if (libPtrs_[i] != nullptr)
180  {
181  if (nLoaded != i)
182  {
183  libPtrs_[nLoaded] = libPtrs_[i];
184  libNames_[nLoaded] = std::move(libNames_[i]);
185  }
186 
187  ++nLoaded;
188  }
189  }
190  }
191 
192  libPtrs_.resize(nLoaded);
193  libNames_.resize(nLoaded);
194 }
195 
196 
198 {
199  if (libName.empty() || libNames_.found(libName))
200  {
201  return false;
202  }
203 
204  libPtrs_.append(nullptr);
205  libNames_.append(libName);
206 
207  return true;
208 }
209 
210 
211 Foam::label Foam::dlLibraryTable::append(const UList<fileName>& libNames)
212 {
213  label nAdded = 0;
214 
215  for (const fileName& libName : libNames)
216  {
217  if (append(libName))
218  {
219  ++nAdded;
220  }
221  }
222 
223  return nAdded;
224 }
225 
226 
227 bool Foam::dlLibraryTable::open(bool verbose)
228 {
229  label nOpen = 0;
230  label nCand = 0; // Number of candidates (have libName but no pointer)
231 
232  forAll(libPtrs_, i)
233  {
234  const fileName& libName = libNames_[i];
235 
236  if (libPtrs_[i] == nullptr && !libName.empty())
237  {
238  ++nCand;
239  void* ptr = openLibrary(libName, verbose);
240 
241  if (ptr)
242  {
243  ++nOpen;
244  libPtrs_[i] = ptr;
245  }
246  else
247  {
248  libNames_[i].clear(); // Avoid trying again
249  }
250  }
251  }
252 
253  return nOpen && nOpen == nCand;
254 }
255 
256 
258 (
259  const fileName& libName,
260  bool verbose
261 )
262 {
263  void* ptr = openLibrary(libName, verbose);
264 
265  if (ptr)
266  {
267  libPtrs_.append(ptr);
268  libNames_.append(libName);
269  }
270 
271  return ptr;
272 }
273 
274 
276 (
277  const UList<fileName>& libNames,
278  bool verbose
279 )
280 {
281  label nOpen = 0;
282 
283  for (const fileName& libName : libNames)
284  {
285  const label index = libNames_.find(libName);
286 
287  if (index >= 0 && libPtrs_[index] != nullptr)
288  {
289  // Already known and opened
290  ++nOpen;
291  }
292  else if (dlLibraryTable::open(libName, verbose))
293  {
294  ++nOpen;
295  }
296  }
297 
298  return nOpen && nOpen == libNames.size();
299 }
300 
301 
303 (
304  const fileName& libName,
305  bool verbose
306 )
307 {
308  const label index = libNames_.rfind(libName);
309 
310  if (index < 0)
311  {
312  return false;
313  }
314 
315  void* ptr = libPtrs_[index];
316 
318  << "Closing " << libName
319  << " with handle " << Foam::name(ptr) << nl;
320 
321  const bool ok = Foam::dlClose(ptr);
322 
323  libPtrs_[index] = nullptr;
324  libNames_[index].clear();
325 
326  if (!ok && verbose)
327  {
329  << "Could not close " << libName << endl;
330  }
331 
332  return ok;
333 }
334 
335 
337 {
338  const label index = libNames_.rfind(libName);
339 
340  if (index < 0)
341  {
342  return nullptr;
343  }
344 
345  return libPtrs_[index];
346 }
347 
348 
350 (
351  const dictionary& dict,
352  const word& libsEntry
353 )
354 {
355  fileNameList libNames;
356  dict.readIfPresent(libsEntry, libNames);
357 
358  label nOpen = 0;
359 
360  for (const fileName& libName : libNames)
361  {
362  if (dlLibraryTable::open(libName)) // verbose = true
363  {
364  ++nOpen;
365  }
366  }
367 
368  return nOpen && nOpen == libNames.size();
369 }
370 
371 
372 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
373 
374 Foam::Ostream& Foam::operator<<
375 (
376  Ostream& os,
377  const InfoProxy<dlLibraryTable>& ip
378 )
379 {
380  const dlLibraryTable& tbl = ip.t_;
381 
382  os << token::BEGIN_LIST << nl;
383 
384  // Lengths of pointers/names are guaranteed interally to be identical
385  forAll(tbl.pointers(), i)
386  {
387  const void* ptr = tbl.pointers()[i];
388  const fileName& libName = tbl.names()[i];
389 
390  // Also write out empty filenames
391  // (specified with '-lib' but did not load)
392 
393  os << Foam::name(ptr) << token::SPACE << libName << nl;
394  }
395 
396  os << token::END_LIST << nl;
397 
398  return os;
399 }
400 
401 
402 // ************************************************************************* //
Foam::dlLibraryTable::pointers
const UList< void * > & pointers() const
Pointers to the libraries in use. Access with caution.
Definition: dlLibraryTable.H:129
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::dlLibraryTable
A table of dynamically loaded libraries.
Definition: dlLibraryTable.H:57
int.H
System signed integer.
Foam::dlLibraryTable::findLibrary
void * findLibrary(const fileName &libName)
Find the handle of the named library.
Definition: dlLibraryTable.C:336
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::InfoProxy
A helper class for outputting values to Ostream.
Definition: InfoProxy.H:47
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::dlLibraryTable::close
bool close(const fileName &libName, bool verbose=true)
Close the named library, optionally warn if problems occur.
Definition: dlLibraryTable.C:303
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::Serr
OSstream Serr
An Ostream wrapper for std::cerr.
Foam::dlLibraryTable::empty
bool empty() const
True if there are no libraries loaded by the table.
Definition: dlLibraryTable.C:105
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::dlLibraryTable::clear
void clear(bool verbose=true)
Clearing closes all libraries loaded by the table.
Definition: dlLibraryTable.C:135
Foam::stringOps::expand
string expand(const std::string &s, const HashTable< string, word, string::hash > &mapping, const char sigil='$')
Definition: stringOps.C:720
Foam::dlLibraryTable::append
bool append(const fileName &libName)
Add to the list of names, but do not yet open.
Definition: dlLibraryTable.C:197
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:360
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::dlLibraryTable::names
const UList< fileName > & names() const
Names of the libraries in use, or requested.
Definition: dlLibraryTable.H:123
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::dlLibraryTable::open
bool open(bool verbose=true)
Definition: dlLibraryTable.C:227
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::List< fileName >
Foam::token::SPACE
Space [isspace].
Definition: token.H:118
dlLibraryTable.H
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::dlClose
bool dlClose(void *handle)
Close a dlopened library using handle. Return true if successful.
Definition: MSwindows.C:1301
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:124
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:309
append
rAUs append(new volScalarField(IOobject::groupName("rAU", phase1.name()), 1.0/(U1Eqn.A()+byDt(max(phase1.residualAlpha() - alpha1, scalar(0)) *rho1))))
Foam::dlLibraryTable::size
label size() const
The number of libraries loaded by the table.
Definition: dlLibraryTable.C:119
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:123
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:298
Foam::dlLibraryTable::dlLibraryTable
dlLibraryTable()=default
Default construct.
Foam::dlOpen
void * dlOpen(const fileName &libName, const bool check=true)
Open a shared library and return handle to library.
Definition: MSwindows.C:1206
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417
Foam::dlLibraryTable::~dlLibraryTable
~dlLibraryTable()
Destructor. Closes all libraries loaded by the table.
Definition: dlLibraryTable.C:97