codedBase.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "codedBase.H"
27 #include "dlLibraryTable.H"
28 #include "regIOobject.H"
29 #include "OSspecific.H"
30 #include "stringOps.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
37 }
38 
39 
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
41 
42 void Foam::codedBase::checkLibrary
43 (
44  const dictionary& dict,
45  const fileName& libPath,
46  void* lib,
47  const string& uniqueFuncName,
48  const bool load
49 ) const
50 {
51  // Provision for manual execution of code before loading/unloading
52  if (dlSymFound(lib, uniqueFuncName))
53  {
54  const loaderFunctionType function =
55  reinterpret_cast<loaderFunctionType>
56  (
57  dlSym(lib, uniqueFuncName)
58  );
59 
60  if (function)
61  {
62  (*function)(load);
63  return;
64  }
65  }
66 
68  << "Failed looking up symbol " << uniqueFuncName << nl
69  << "from " << libPath << exit(FatalIOError);
70 }
71 
72 
73 void* Foam::codedBase::loadLibrary
74 (
75  const dictionary& dict,
76  const fileName& libPath,
77  const string& uniqueFuncName
78 ) const
79 {
80  if (libPath.empty())
81  {
82  return 0;
83  }
84 
85  void* lib = dynamicCode::loadLibrary(libPath);
86 
87  if (lib)
88  {
89  checkLibrary(dict, libPath, lib, uniqueFuncName, true);
90  }
91 
92  return lib;
93 }
94 
95 
96 void Foam::codedBase::unloadLibrary
97 (
98  const dictionary& dict,
99  const fileName& libPath,
100  const string& uniqueFuncName
101 ) const
102 {
103  if (libPath.empty())
104  {
105  return;
106  }
107 
108  void* lib = libs.findLibrary(libPath);
109 
110  if (!lib)
111  {
112  return;
113  }
114 
115  checkLibrary(dict, libPath, lib, uniqueFuncName, false);
116 
117  if (!libs.close(libPath, false))
118  {
120  << "Failed unloading library " << libPath
121  << exit(FatalIOError);
122  }
123 }
124 
125 
126 Foam::verbatimString Foam::codedBase::expandCodeString
127 (
128  const dictionary& dict,
129  const word& codeKey,
130  const word& codeDictVar
131 ) const
132 {
133  verbatimString codeString;
134 
135  if (dict.found(codeKey))
136  {
137  codeString = dict.lookupOrDefault<verbatimString>
138  (
139  codeKey,
141  );
142 
144  (
145  codeString,
146  dict,
147  codeDictVar
148  );
149  }
150 
151  return codeString;
152 }
153 
154 
155 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
156 
158 (
159  const word& name,
160  const dictionary& dict,
161  const wordList& codeKeys,
162  const wordList& codeDictVars,
163  const word& codeOptionsFileName,
164  const wordList& compileFiles,
165  const wordList& copyFiles,
166  const bool reloadable
167 )
168 :
170  (
171  dict,
172  codedName(name),
173  codedName(name),
174  codeKeys,
175  codeDictVars,
176  codeOptionsFileName,
177  compileFiles,
178  copyFiles
179  ),
180  reloadable_(reloadable)
181 {}
182 
183 
184 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
185 
187 {
188  if (reloadable_)
189  {
190  unloadLibrary
191  (
192  dictionary(),
193  oldLibPath_,
194  dynamicCode::libraryBaseName(oldLibPath_)
195  );
196  }
197 }
198 
199 
200 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
201 
203 {
204  word result(name);
205 
206  if (!isalpha(result[0]))
207  {
209  << "Cannot construct code name from function name \"" << name
210  << "\" as the first character is not alphabetic"
211  << exit(FatalError);
212  }
213 
214  for (word::size_type i = 1; i < name.size(); ++ i)
215  {
216  const bool valid = isalnum(result[i]) || result[i] == '_';
217 
218  if (!valid)
219  {
220  result[i] = '_';
221  }
222  }
223 
224  return result;
225 }
226 
227 
228 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
229 
231 {
232  const fileName libPath = this->libPath();
233 
234  // The correct library was already loaded => we are done
235  if (libs.findLibrary(libPath))
236  {
237  return false;
238  }
239 
240  Info<< "Using dynamicCode for " << type() << " " << codeName()
241  << " at line " << dict.startLineNumber()
242  << " in " << dict.name() << endl;
243 
244  // May need to unload old library
245  unloadLibrary
246  (
247  dict,
248  oldLibPath_,
249  dynamicCode::libraryBaseName(oldLibPath_)
250  );
251 
252  // Try loading an existing library (avoid compilation when possible)
253  if (!loadLibrary(dict, libPath, codeSha1Name()))
254  {
255  createLibrary(dict);
256 
257  if (!loadLibrary(dict, libPath, codeSha1Name()))
258  {
260  << "Failed to load " << libPath << exit(FatalIOError);
261  }
262  }
263 
264  // Retain for future reference
265  oldLibPath_ = libPath;
266 
267  return true;
268 }
269 
270 
271 // ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
Base class for coded functionObjects, fvModels, Function1, Function2.
Definition: codedBase.H:53
codedBase(const word &name, const dictionary &dict, const wordList &codeKeys, const wordList &codeDictVars, const word &codeOptionsFileName, const wordList &compileFiles, const wordList &copyFiles, const bool reloadable=true)
Construct from name and dictionary.
Definition: codedBase.C:158
virtual ~codedBase()
Destructor.
Definition: codedBase.C:186
static word codedName(const word &name)
Create a coded name from the given name.
Definition: codedBase.C:202
bool updateLibrary(const dictionary &dict) const
Update library from given updated dictionary as required.
Definition: codedBase.C:230
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:111
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
T lookupOrDefault(const word &, const T &) const
Find and return a T, if not found return the given default.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:468
virtual label startLineNumber() const
Return line number of first token in dictionary.
Definition: dictionary.C:401
bool close(const fileName &name, const bool verbose=true)
Close the named library, optionally with warnings if problems occur.
void * findLibrary(const fileName &libName)
Find the handle of the named library.
Encapsulation of dynamic code dictionaries and functionality.
Definition: dynamicCode.H:51
fileName libPath() const
Library path for specified code name.
Definition: dynamicCode.H:239
void * loadLibrary(const fileName &libPath) const
Definition: dynamicCode.C:613
static word libraryBaseName(const fileName &libPath)
Return the library basename without leading 'lib' or trailing '.so'.
Definition: dynamicCode.C:472
A class for handling file names.
Definition: fileName.H:82
A class for handling verbatimStrings, derived from string.
static const verbatimString null
An empty verbatimString.
A class for handling words, derived from string.
Definition: word.H:63
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
bool valid(const PtrList< ModelType > &l)
string & inplaceExpandCodeString(string &, const dictionary &dict, const word &dictVar="dict", const char sigil='$')
Inplace expand occurrences of variables according to the dictionary.
Definition: stringOps.C:410
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dlLibraryTable libs
Table of loaded dynamic libraries.
bool dlSymFound(void *handle, const std::string &symbol)
Report if symbol in a dlopened library could be found.
Definition: POSIX.C:1305
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void * dlSym(void *handle, const std::string &symbol)
Lookup a symbol in a dlopened library using handle to library.
Definition: POSIX.C:1276
error FatalError
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
static const char nl
Definition: Ostream.H:297
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
dictionary dict