Merge branch 'feature-dynamicLibrary' into 'develop'

Feature dynamic library - issue #1737

See merge request Development/openfoam!375
This commit is contained in:
Andrew Heather
2020-07-14 16:41:39 +01:00
39 changed files with 649 additions and 254 deletions

View File

@ -0,0 +1,3 @@
Test-dynamicLibrary.C
EXE = $(FOAM_USER_APPBIN)/Test-dynamicLibrary

View File

@ -0,0 +1,2 @@
EXE_INC =
EXE_LIBS =

View File

@ -0,0 +1,143 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-dynamicLibrary
Description
Test loading/unloading of libraries
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "profiling.H"
#include "DynamicList.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote("Low-level test of library load/unload");
profiling::disable(); // No profiling output
argList::noBanner();
argList::noParallel();
argList::removeOption("case");
argList::removeOption("noFunctionObjects");
argList::addBoolOption("no-close", "Skip dlclose");
argList::addBoolOption("quiet", "Disable verbosity");
argList::addArgument("lib...");
argList::noMandatoryArgs(); // Arguments are optional
argList args(argc, argv, false, true);
const bool noClose = args.found("no-close");
const bool verbose = !args.found("quiet");
//- Pointers to the loaded libraries
DynamicList<void*> libPtrs_;
//- Names of loaded libraries, or of libraries to be loaded
DynamicList<fileName> libNames_;
label nbad = 0;
wordHashSet loaded;
for (int argi = 1; argi < args.size(); ++argi)
{
const fileName libName(fileName::validate(args[argi]));
if (libName.empty())
{
continue;
}
void* ptr = Foam::dlOpen(libName, false);
if (!ptr)
{
++nbad;
}
else
{
libPtrs_.append(ptr);
libNames_.append(libName);
if (verbose)
{
const word addr(Foam::name(ptr));
if (loaded.insert(addr))
{
InfoErr << "Can load " << libName << nl;
}
else
{
InfoErr << "Already loaded " << libName << nl;
}
}
}
}
if (!noClose)
{
forAllReverse(libPtrs_, i)
{
void* ptr = libPtrs_[i];
if (ptr == nullptr)
{
libNames_[i].clear();
continue;
}
const bool ok = Foam::dlClose(ptr);
if (verbose)
{
if (ok)
{
InfoErr << "Closed ";
}
else
{
InfoErr << "Failed closing ";
}
InfoErr
<< libNames_[i]
<< " with handle " << Foam::name(ptr) << nl;
}
}
}
return 0;
}
// ************************************************************************* //

View File

@ -471,7 +471,7 @@ Foam::Time::Time
if (enableLibs) if (enableLibs)
{ {
libs_.open(controlDict_, "libs"); libs_.open("libs", controlDict_);
} }
// Explicitly set read flags on objectRegistry so anything constructed // Explicitly set read flags on objectRegistry so anything constructed
@ -553,12 +553,9 @@ Foam::Time::Time
// Libraries // Libraries
// //
// * enable by default unless '-no-libs' option was used // * enable by default unless '-no-libs' option was used
if (!args.found("no-libs")) if (enableLibs && !args.found("no-libs"))
{ {
if (enableLibs) libs_.open("libs", controlDict_);
{
libs_.open(controlDict_, "libs");
}
} }
// Explicitly set read flags on objectRegistry so anything constructed // Explicitly set read flags on objectRegistry so anything constructed
@ -634,7 +631,7 @@ Foam::Time::Time
if (enableLibs) if (enableLibs)
{ {
libs_.open(controlDict_, "libs"); libs_.open("libs", controlDict_);
} }
@ -708,7 +705,7 @@ Foam::Time::Time
if (enableLibs) if (enableLibs)
{ {
libs_.open(controlDict_, "libs"); libs_.open("libs", controlDict_);
} }
setMonitoring(); // for profiling etc setMonitoring(); // for profiling etc

View File

@ -130,14 +130,14 @@ public:
private: private:
// Private data // Private Data
//- Profiling trigger for time-loop (for run, loop) //- Profiling trigger for time-loop (for run, loop)
mutable std::unique_ptr<profilingTrigger> loopProfiling_; mutable std::unique_ptr<profilingTrigger> loopProfiling_;
//- Any loaded dynamic libraries. Make sure to construct before //- Any loaded dynamic libraries
// reading controlDict. // Construct before reading controlDict
dlLibraryTable libs_; mutable dlLibraryTable libs_;
//- The controlDict //- The controlDict
unwatchedIOdictionary controlDict_; unwatchedIOdictionary controlDict_;
@ -145,7 +145,7 @@ private:
protected: protected:
// Protected data // Protected Data
label startTimeIndex_; label startTimeIndex_;
@ -502,14 +502,8 @@ public:
return functionObjects_; return functionObjects_;
} }
//- External access to the loaded libraries //- Mutable access to the loaded dynamic libraries
const dlLibraryTable& libs() const dlLibraryTable& libs() const
{
return libs_;
}
//- External access to the loaded libraries
dlLibraryTable& libs()
{ {
return libs_; return libs_;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd. Copyright (C) 2018-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -73,7 +73,7 @@ Foam::dlLibraryTable& Foam::functionEntries::codeStream::libs
( (
dict.topDict() dict.topDict()
); );
return const_cast<Time&>(d.time()).libs(); return d.time().libs();
} }
@ -145,18 +145,13 @@ Foam::functionEntries::codeStream::getFunction
if (isA<baseIOdictionary>(topDict)) if (isA<baseIOdictionary>(topDict))
{ {
// Cached access to dl libs. Guarantees clean up upon destruction // Cached access to libs, with cleanup upon termination
// of Time. lib = libs(parentDict).open(libPath, false);
dlLibraryTable& dlLibs = libs(parentDict);
if (dlLibs.open(libPath, false))
{
lib = dlLibs.findLibrary(libPath);
}
} }
else else
{ {
// Uncached opening of libPath. Do not complain if cannot be loaded // Uncached opening of libPath. Do not complain if cannot be loaded
lib = dlOpen(libPath, false); lib = Foam::dlOpen(libPath, false);
} }
} }
@ -299,14 +294,13 @@ Foam::functionEntries::codeStream::getFunction
if (isA<baseIOdictionary>(topDict)) if (isA<baseIOdictionary>(topDict))
{ {
// Cached access to dl libs. Guarantees clean up upon destruction // Cached access to libs, with cleanup upon termination
// of Time.
dlLibraryTable& dlLibs = libs(parentDict);
DebugPout DebugPout
<< "Opening cached dictionary:" << libPath << endl; << "Opening cached dictionary:" << libPath << endl;
if (!dlLibs.open(libPath, false)) lib = libs(parentDict).open(libPath, false);
if (!lib)
{ {
FatalIOErrorInFunction(parentDict) FatalIOErrorInFunction(parentDict)
<< "Failed loading library " << libPath << nl << "Failed loading library " << libPath << nl
@ -314,8 +308,6 @@ Foam::functionEntries::codeStream::getFunction
<< " in system/controlDict?" << " in system/controlDict?"
<< exit(FatalIOError); << exit(FatalIOError);
} }
lib = dlLibs.findLibrary(libPath);
} }
else else
{ {
@ -323,7 +315,7 @@ Foam::functionEntries::codeStream::getFunction
DebugPout DebugPout
<< "Opening uncached dictionary:" << libPath << endl; << "Opening uncached dictionary:" << libPath << endl;
lib = dlOpen(libPath, true); lib = Foam::dlOpen(libPath, true);
} }
} }
@ -346,7 +338,7 @@ Foam::functionEntries::codeStream::getFunction
streamingFunctionType function = streamingFunctionType function =
reinterpret_cast<streamingFunctionType> reinterpret_cast<streamingFunctionType>
( (
dlSym(lib, dynCode.codeName()) Foam::dlSym(lib, dynCode.codeName())
); );

View File

@ -98,12 +98,7 @@ void* Foam::codedBase::loadLibrary
{ {
// Avoid compilation by loading an existing library // Avoid compilation by loading an existing library
void* handle = void* handle = libs().open(libPath, false);
(
!libPath.empty() && libs().open(libPath, false)
? libs().findLibrary(libPath)
: nullptr
);
if (!handle) if (!handle)
{ {
@ -115,25 +110,9 @@ void* Foam::codedBase::loadLibrary
// Manual execution of code after loading. // Manual execution of code after loading.
// This is mandatory for codedBase. // This is mandatory for codedBase.
void* rawSymbol = dlSymFind(handle, funcName); const bool ok = libs().loadHook(handle, funcName, false);
if (rawSymbol) if (!ok)
{
loaderType fun = reinterpret_cast<loaderType>(rawSymbol);
if (fun)
{
(*fun)(true); // force load
}
else
{
FatalIOErrorInFunction(context.dict())
<< "Failed symbol lookup " << funcName.c_str() << nl
<< "from " << libPath << nl
<< exit(FatalIOError);
}
}
else
{ {
FatalIOErrorInFunction(context.dict()) FatalIOErrorInFunction(context.dict())
<< "Failed symbol lookup " << funcName.c_str() << nl << "Failed symbol lookup " << funcName.c_str() << nl
@ -160,12 +139,7 @@ void Foam::codedBase::unloadLibrary
const dynamicCodeContext& context const dynamicCodeContext& context
) const ) const
{ {
void* handle = void* handle = libs().open(libPath, false);
(
!libPath.empty() && libs().open(libPath, false)
? libs().findLibrary(libPath)
: nullptr
);
if (!handle) if (!handle)
{ {
@ -175,23 +149,13 @@ void Foam::codedBase::unloadLibrary
// Manual execution of code before unloading. // Manual execution of code before unloading.
// This is mandatory for codedBase. // This is mandatory for codedBase.
void* rawSymbol = dlSymFind(handle, funcName); const bool ok = libs().unloadHook(handle, funcName, false);
if (rawSymbol) if (!ok)
{ {
loaderType fun = reinterpret_cast<loaderType>(rawSymbol); IOWarningInFunction(context.dict())
<< "Failed looking up symbol " << funcName << nl
if (fun) << "from " << libPath << nl;
{
(*fun)(false); // force unload
}
else
{
FatalIOErrorInFunction(context.dict())
<< "Failed symbol lookup " << funcName.c_str() << nl
<< "from " << libPath << nl
<< exit(FatalIOError);
}
} }
if (!libs().close(libPath, false)) if (!libs().close(libPath, false))
@ -389,7 +353,7 @@ void Foam::codedBase::updateLibrary
unloadLibrary unloadLibrary
( (
oldLibPath_, oldLibPath_,
dynamicCode::libraryBaseName(oldLibPath_), dlLibraryTable::basename(oldLibPath_),
context context
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -49,6 +49,7 @@ SourceFiles
#include "dictionary.H" #include "dictionary.H"
#include "dynamicCodeContext.H" #include "dynamicCodeContext.H"
#include "fileName.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -75,13 +76,6 @@ class codedBase
mutable fileName oldLibPath_; mutable fileName oldLibPath_;
// Data Types
//- Global loader/unloader function type
// Called with true on load, false on unload.
typedef void (*loaderType)(bool);
// Private Member Functions // Private Member Functions
//- Load specified library and execute funcName(true) //- Load specified library and execute funcName(true)
@ -107,12 +101,6 @@ class codedBase
const dynamicCodeContext& context const dynamicCodeContext& context
) const; ) const;
//- No copy construct
codedBase(const codedBase&) = delete;
//- No copy assignment
void operator=(const codedBase&) = delete;
protected: protected:
@ -148,7 +136,7 @@ protected:
//- or use the codeDict() to generate one //- or use the codeDict() to generate one
void updateLibrary(const word& name) const; void updateLibrary(const word& name) const;
//- Get the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const = 0; virtual dlLibraryTable& libs() const = 0;
//- Adapt the context for the current object //- Adapt the context for the current object
@ -168,6 +156,13 @@ protected:
virtual const dictionary& codeDict() const = 0; virtual const dictionary& codeDict() const = 0;
//- No copy construct
codedBase(const codedBase&) = delete;
//- No copy assignment
void operator=(const codedBase&) = delete;
public: public:
//- Runtime type information //- Runtime type information
@ -176,7 +171,7 @@ public:
// Constructors // Constructors
//- Construct null //- Default construct
codedBase() = default; codedBase() = default;

View File

@ -29,7 +29,15 @@ License
#include "dlLibraryTable.H" #include "dlLibraryTable.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "IOstreams.H" #include "IOstreams.H"
#include "int.H"
// Could be constexpr in the header if required
#ifdef __APPLE__
#define EXT_SO "dylib"
#elif defined _WIN32
#define EXT_SO "dll"
#else
#define EXT_SO "so"
#endif
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -38,6 +46,115 @@ namespace Foam
defineTypeNameAndDebug(dlLibraryTable, 0); defineTypeNameAndDebug(dlLibraryTable, 0);
} }
std::unique_ptr<Foam::dlLibraryTable> Foam::dlLibraryTable::global_(nullptr);
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::word Foam::dlLibraryTable::basename(const fileName& libPath)
{
word libName(libPath.nameLessExt());
libName.removeStart("lib"); // Remove leading 'lib' from name
return libName;
}
Foam::word Foam::dlLibraryTable::fullname(word libName)
{
if (libName.empty())
{
return libName;
}
// Add leading 'lib' and trailing '.so'
return "lib" + libName.ext(EXT_SO);
}
Foam::dlLibraryTable& Foam::dlLibraryTable::libs()
{
if (!global_)
{
global_.reset(new dlLibraryTable{});
}
return *global_;
}
bool Foam::dlLibraryTable::functionHook
(
const bool load,
void* handle,
const std::string& funcName,
const bool verbose,
const std::string& context
)
{
if (!handle || funcName.empty())
{
return false;
}
bool ok = false;
void* symbol = Foam::dlSymFind(handle, funcName);
if (symbol)
{
// Execute loader/unloader code
try
{
loaderType fun = reinterpret_cast<loaderType>(symbol);
if (fun)
{
(*fun)(load);
ok = true;
}
}
catch (...)
{}
}
if (verbose && !ok)
{
auto& err = WarningInFunction
<< "Failed symbol lookup " << funcName.c_str() << nl;
if (!context.empty())
{
err << "from " << context.c_str() << nl;
}
}
return ok;
}
bool Foam::dlLibraryTable::loadHook
(
void* handle,
const std::string& funcName,
const bool verbose,
const std::string& context
)
{
return functionHook(true, handle, funcName, verbose, context);
}
bool Foam::dlLibraryTable::unloadHook
(
void* handle,
const std::string& funcName,
const bool verbose,
const std::string& context
)
{
return functionHook(false, handle, funcName, verbose, context);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -84,14 +201,39 @@ Foam::dlLibraryTable::dlLibraryTable
Foam::dlLibraryTable::dlLibraryTable Foam::dlLibraryTable::dlLibraryTable
( (
const dictionary& dict, std::initializer_list<fileName> libNames,
const word& libsEntry bool verbose
) )
{ {
dlLibraryTable::open(dict, libsEntry); dlLibraryTable::open(libNames, verbose);
} }
Foam::dlLibraryTable::dlLibraryTable
(
const word& libsEntry,
const dictionary& dict,
bool verbose
)
{
fileNameList libNames;
dict.readIfPresent(libsEntry, libNames);
dlLibraryTable::open(libNames, verbose);
}
Foam::dlLibraryTable::dlLibraryTable
(
const dictionary& dict,
const word& libsEntry,
bool verbose
)
:
dlLibraryTable(libsEntry, dict, verbose)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::dlLibraryTable::~dlLibraryTable() Foam::dlLibraryTable::~dlLibraryTable()
@ -132,6 +274,30 @@ Foam::label Foam::dlLibraryTable::size() const
} }
Foam::List<Foam::fileName> Foam::dlLibraryTable::loaded() const
{
List<fileName> list(libNames_.size());
label nLoaded = 0;
forAll(libNames_, i)
{
void* ptr = libPtrs_[i];
const fileName& libName = libNames_[i];
if (ptr != nullptr && !libName.empty())
{
list[nLoaded] = libName;
++nLoaded;
}
}
list.resize(nLoaded);
return list;
}
void Foam::dlLibraryTable::clear(bool verbose) void Foam::dlLibraryTable::clear(bool verbose)
{ {
label nLoaded = 0; label nLoaded = 0;
@ -231,12 +397,14 @@ bool Foam::dlLibraryTable::open(bool verbose)
forAll(libPtrs_, i) forAll(libPtrs_, i)
{ {
void* ptr = libPtrs_[i];
const fileName& libName = libNames_[i]; const fileName& libName = libNames_[i];
if (libPtrs_[i] == nullptr && !libName.empty()) if (ptr == nullptr && !libName.empty())
{ {
++nCand; ++nCand;
void* ptr = openLibrary(libName, verbose);
ptr = openLibrary(libName, verbose);
if (ptr) if (ptr)
{ {
@ -260,6 +428,7 @@ void* Foam::dlLibraryTable::open
bool verbose bool verbose
) )
{ {
// Handles empty name silently
void* ptr = openLibrary(libName, verbose); void* ptr = openLibrary(libName, verbose);
if (ptr) if (ptr)
@ -278,7 +447,34 @@ bool Foam::dlLibraryTable::open
bool verbose bool verbose
) )
{ {
label nOpen = 0; decltype(libNames.size()) nOpen = 0;
for (const fileName& libName : libNames)
{
const label index = libNames_.find(libName);
if (index >= 0 && libPtrs_[index] != nullptr)
{
// Already known and opened
++nOpen;
}
else if (dlLibraryTable::open(libName, verbose))
{
++nOpen;
}
}
return nOpen && nOpen == libNames.size();
}
bool Foam::dlLibraryTable::open
(
std::initializer_list<fileName> libNames,
bool verbose
)
{
decltype(libNames.size()) nOpen = 0;
for (const fileName& libName : libNames) for (const fileName& libName : libNames)
{ {
@ -307,13 +503,19 @@ bool Foam::dlLibraryTable::close
{ {
const label index = libNames_.rfind(libName); const label index = libNames_.rfind(libName);
if (index < 0) if (index < 0 || libName.empty())
{ {
return false; return false;
} }
void* ptr = libPtrs_[index]; void* ptr = libPtrs_[index];
if (ptr == nullptr)
{
libNames_[index].clear();
return false;
}
DebugInFunction DebugInFunction
<< "Closing " << libName << "Closing " << libName
<< " with handle " << Foam::name(ptr) << nl; << " with handle " << Foam::name(ptr) << nl;
@ -323,7 +525,23 @@ bool Foam::dlLibraryTable::close
libPtrs_[index] = nullptr; libPtrs_[index] = nullptr;
libNames_[index].clear(); libNames_[index].clear();
if (!ok && verbose) if (ok)
{
// From man dlopen(3)
// ...
// a dynamically loaded shared object is not deallocated until
// dlclose() has been called on it as many times as dlopen()
// has succeeded on it.
// Handle aliased library names
for (label idx = 0; (idx = libPtrs_.find(ptr, idx)) >= 0; ++idx)
{
(void) Foam::dlClose(ptr);
libPtrs_[idx] = nullptr;
libNames_[idx].clear();
}
}
else if (verbose)
{ {
WarningInFunction WarningInFunction
<< "Could not close " << libName << endl; << "Could not close " << libName << endl;
@ -337,7 +555,7 @@ void* Foam::dlLibraryTable::findLibrary(const fileName& libName)
{ {
const label index = libNames_.rfind(libName); const label index = libNames_.rfind(libName);
if (index < 0) if (index < 0 || libName.empty())
{ {
return nullptr; return nullptr;
} }
@ -346,26 +564,29 @@ void* Foam::dlLibraryTable::findLibrary(const fileName& libName)
} }
bool Foam::dlLibraryTable::open
(
const word& libsEntry,
const dictionary& dict,
bool verbose
)
{
fileNameList libNames;
return
(
dict.readIfPresent(libsEntry, libNames)
&& dlLibraryTable::open(libNames, verbose)
);
}
bool Foam::dlLibraryTable::open bool Foam::dlLibraryTable::open
( (
const dictionary& dict, const dictionary& dict,
const word& libsEntry const word& libsEntry
) )
{ {
fileNameList libNames; return dlLibraryTable::open(libsEntry, dict, true); // verbose = true
dict.readIfPresent(libsEntry, libNames);
label nOpen = 0;
for (const fileName& libName : libNames)
{
if (dlLibraryTable::open(libName)) // verbose = true
{
++nOpen;
}
}
return nOpen && nOpen == libNames.size();
} }
@ -381,7 +602,7 @@ Foam::Ostream& Foam::operator<<
os << token::BEGIN_LIST << nl; os << token::BEGIN_LIST << nl;
// Lengths of pointers/names are guaranteed interally to be identical // Lengths of pointers/names are guaranteed internally to be identical
forAll(tbl.pointers(), i) forAll(tbl.pointers(), i)
{ {
const void* ptr = tbl.pointers()[i]; const void* ptr = tbl.pointers()[i];

View File

@ -30,6 +30,10 @@ Class
Description Description
A table of dynamically loaded libraries. A table of dynamically loaded libraries.
SeeAlso
Foam::dlOpen
Foam::dlClose
SourceFiles SourceFiles
dlLibraryTable.C dlLibraryTable.C
dlLibraryTableTemplates.C dlLibraryTableTemplates.C
@ -40,7 +44,9 @@ SourceFiles
#define dlLibraryTable_H #define dlLibraryTable_H
#include "DynamicList.H" #include "DynamicList.H"
#include "fileName.H"
#include "InfoProxy.H" #include "InfoProxy.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -57,15 +63,35 @@ Ostream& operator<<(Ostream& os, const InfoProxy<dlLibraryTable>& info);
class dlLibraryTable class dlLibraryTable
{ {
// Static Data
//- Global singleton of dynamic libraries
static std::unique_ptr<dlLibraryTable> global_;
// Private Data // Private Data
//- Pointers to the loaded libraries
DynamicList<void*> libPtrs_; DynamicList<void*> libPtrs_;
//- Names of loaded libraries, or of libraries to be loaded
DynamicList<fileName> libNames_; DynamicList<fileName> libNames_;
// Private Member Functions // Private Member Functions
//- Load/unload hook.
// \return true if the function was found and executed
static bool functionHook
(
const bool load, //!< true = on-load, false = on-unload
void* handle, //!< library handle
const std::string& funcName,
const bool verbose,
const std::string& context
);
//- Open specified library name and return pointer. //- Open specified library name and return pointer.
// Warning messages, but no additional side-effects. // Warning messages, but no additional side-effects.
void* openLibrary(const fileName& libName, bool verbose); void* openLibrary(const fileName& libName, bool verbose);
@ -73,9 +99,17 @@ class dlLibraryTable
public: public:
// Declare name of the class and its debug switch // Public Data Types
//- Global loader/unloader function type (C-linkage)
// Called with true on load, false on unload.
typedef void (*loaderType)(bool);
//- Declare name of the class and its debug switch
ClassName("dlLibraryTable"); ClassName("dlLibraryTable");
// Generated Methods // Generated Methods
//- Default construct //- Default construct
@ -96,22 +130,82 @@ public:
// Constructors // Constructors
//- Open specified libraries. Ignores duplicate names. //- Open specified libraries, warn by default if problems occur
// Ignores duplicate names.
explicit dlLibraryTable explicit dlLibraryTable
( (
const UList<fileName>& libNames, const UList<fileName>& libNames,
bool verbose = true bool verbose = true
); );
//- Open all libraries listed in the 'libsEntry' entry in the //- Open specified libraries, warn by default if problems occur
//- given dictionary. Verbose = true. // Ignores duplicate names.
dlLibraryTable(const dictionary& dict, const word& libsEntry); explicit dlLibraryTable
(
std::initializer_list<fileName> libNames,
bool verbose = true
);
//- Open libraries listed in 'libsEntry' entry in the dictionary,
//- warn by default if problems occur
dlLibraryTable
(
const word& libsEntry,
const dictionary& dict,
bool verbose = true
);
//- Open libraries listed in 'libsEntry' entry in the dictionary,
//- warn by default if problems occur
dlLibraryTable
(
const dictionary& dict,
const word& libsEntry,
bool verbose = true
);
//- Destructor. Closes all libraries loaded by the table. //- Destructor. Closes all libraries loaded by the table.
~dlLibraryTable(); ~dlLibraryTable();
// Static Member Functions
//- Library basename without leading 'lib' or trailing '.so'
static word basename(const fileName& libPath);
//- Library fullname, prefix with 'lib', suffix with '.so'
// \note the suffix is system-dependent
static word fullname(word libName);
//- Table of global libraries
static dlLibraryTable& libs();
//- Low-level interface to execute global "void funcName(true)"
//- from the library, typically for additional loading.
// If called, it should be the first step after opening a library.
// \return true if the function was found and executed
static bool loadHook
(
void* handle,
const std::string& funcName,
const bool verbose = false,
const std::string& context = "" //!< Calling context for warnings
);
//- Low-level interface to execute global "void funcName(false)"
//- from the library, typically for unloading.
// If called, it should be the last step before closing a library.
// \return true if the function was found and executed
static bool unloadHook
(
void* handle,
const std::string& funcName,
const bool verbose = false,
const std::string& context = "" //!< Calling context for warnings
);
// Member Functions // Member Functions
//- True if there are no libraries loaded by the table //- True if there are no libraries loaded by the table
@ -120,6 +214,9 @@ public:
//- The number of libraries loaded by the table //- The number of libraries loaded by the table
label size() const; label size() const;
//- Names of the libraries in use
List<fileName> loaded() const;
//- Names of the libraries in use, or requested //- Names of the libraries in use, or requested
const UList<fileName>& names() const const UList<fileName>& names() const
{ {
@ -147,21 +244,41 @@ public:
//- These names will normally have been added with the append() method. //- These names will normally have been added with the append() method.
bool open(bool verbose = true); bool open(bool verbose = true);
//- Open the named library, optionally warn if problems occur //- Open the named library, warn by default if problems occur.
// An empty name is a silent no-op and always returns nullptr.
// \return a pointer to the library opened, or nullptr on failure.
void* open(const fileName& libName, bool verbose = true); void* open(const fileName& libName, bool verbose = true);
//- Open the named libraries, optionally warn if problems occur //- Open the named libraries, warn by default if problems occur.
// Ignores duplicate names. // Ignores duplicate names.
bool open(const UList<fileName>& libNames, bool verbose = true); bool open(const UList<fileName>& libNames, bool verbose = true);
//- Open the named libraries, warn by default if problems occur.
// Ignores duplicate names.
bool open
(
std::initializer_list<fileName> libNames,
bool verbose = true
);
//- Close the named library, optionally warn if problems occur //- Close the named library, optionally warn if problems occur
// Using an empty name is a no-op and always returns false.
bool close(const fileName& libName, bool verbose = true); bool close(const fileName& libName, bool verbose = true);
//- Find the handle of the named library //- Find the handle of the named library
// Using an empty name is a no-op and always returns nullptr.
void* findLibrary(const fileName& libName); void* findLibrary(const fileName& libName);
//- Open all libraries listed in the 'libsEntry' entry in the //- Open libraries listed in the 'libsEntry' entry in the dictionary.
//- given dictionary. bool open
(
const word& libsEntry,
const dictionary& dict,
bool verbose = true
);
//- Open libraries listed in the 'libsEntry' entry in the dictionary.
// Verbose = true
bool open(const dictionary& dict, const word& libsEntry); bool open(const dictionary& dict, const word& libsEntry);
//- Open all libraries listed in the 'libsEntry' entry in the //- Open all libraries listed in the 'libsEntry' entry in the
@ -172,7 +289,8 @@ public:
( (
const dictionary& dict, const dictionary& dict,
const word& libsEntry, const word& libsEntry,
const TablePtr& tablePtr const TablePtr& tablePtr,
bool verbose = true
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,7 +28,6 @@ License
#include "dlLibraryTable.H" #include "dlLibraryTable.H"
#include "dictionary.H" #include "dictionary.H"
#include "fileNameList.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -37,23 +36,24 @@ bool Foam::dlLibraryTable::open
( (
const dictionary& dict, const dictionary& dict,
const word& libsEntry, const word& libsEntry,
const TablePtr& tablePtr const TablePtr& tablePtr,
bool verbose
) )
{ {
fileNameList libNames; List<fileName> libNames;
dict.readIfPresent(libsEntry, libNames); dict.readIfPresent(libsEntry, libNames);
label nOpen = 0; label nOpen = 0;
for (const fileName& libName : libNames) for (const fileName& libName : libNames)
{ {
const label nEntries = (tablePtr ? tablePtr->size() : 0); const label nEntries = (tablePtr ? tablePtr->size() : -1);
if (dlLibraryTable::open(libName)) if (dlLibraryTable::open(libName, verbose))
{ {
++nOpen; ++nOpen;
if (debug && (!tablePtr || tablePtr->size() <= nEntries)) if (debug && tablePtr != nullptr && tablePtr->size() <= nEntries)
{ {
WarningInFunction WarningInFunction
<< "library " << libName << "library " << libName
@ -61,12 +61,6 @@ bool Foam::dlLibraryTable::open
<< nl << endl; << nl << endl;
} }
} }
else
{
WarningInFunction
<< "Could not open library " << libName
<< nl << endl;
}
} }
return nOpen && nOpen == libNames.size(); return nOpen && nOpen == libNames.size();

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,6 +28,7 @@ License
#include "dynamicCode.H" #include "dynamicCode.H"
#include "dynamicCodeContext.H" #include "dynamicCodeContext.H"
#include "dlLibraryTable.H"
#include "argList.H" #include "argList.H"
#include "stringOps.H" #include "stringOps.H"
#include "Fstream.H" #include "Fstream.H"
@ -37,15 +38,6 @@ License
#include "dictionary.H" #include "dictionary.H"
#include "foamVersion.H" #include "foamVersion.H"
#ifdef __APPLE__
#define EXT_SO ".dylib"
#elif defined _WIN32
#define EXT_SO ".dll"
#else
#define EXT_SO ".so"
#endif
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::dynamicCode::allowSystemOperations int Foam::dynamicCode::allowSystemOperations
@ -103,14 +95,6 @@ void Foam::dynamicCode::checkSecurity
} }
Foam::word Foam::dynamicCode::libraryBaseName(const fileName& libPath)
{
word libName(libPath.nameLessExt());
libName.removeStart("lib"); // Remove leading 'lib' from name
return libName;
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::dynamicCode::copyAndFilter void Foam::dynamicCode::copyAndFilter
@ -157,7 +141,7 @@ bool Foam::dynamicCode::resolveTemplates
DynamicList<fileName>& badFiles DynamicList<fileName>& badFiles
) )
{ {
// Try to get template from FOAM_CODESTREAM_TEMPLATES // Try to get template from FOAM_CODE_TEMPLATES
const fileName templateDir(Foam::getEnv(codeTemplateEnvName)); const fileName templateDir(Foam::getEnv(codeTemplateEnvName));
bool allOkay = true; bool allOkay = true;
@ -328,13 +312,13 @@ Foam::fileName Foam::dynamicCode::codeRelPath() const
Foam::fileName Foam::dynamicCode::libPath() const Foam::fileName Foam::dynamicCode::libPath() const
{ {
return codeRoot_/libSubDir_/"lib" + codeName_ + EXT_SO; return codeRoot_/libSubDir_/dlLibraryTable::fullname(codeName_);
} }
Foam::fileName Foam::dynamicCode::libRelPath() const Foam::fileName Foam::dynamicCode::libRelPath() const
{ {
return codeRelPath()/libSubDir_/"lib" + codeName_ + EXT_SO; return codeRelPath()/libSubDir_/dlLibraryTable::fullname(codeName_);
} }
@ -514,16 +498,10 @@ bool Foam::dynamicCode::wmakeLibso() const
// cmd[0] = stringOps::expand("$WM_PROJECT_DIR/wmake/wmake"); // cmd[0] = stringOps::expand("$WM_PROJECT_DIR/wmake/wmake");
// This can take a bit longer, so report that we are starting wmake // This can take a bit longer, so report that we are starting wmake
// Even with details turned off, we want some feedback
if (Foam::infoDetailLevel > 0) OSstream& os = (Foam::infoDetailLevel > 0 ? Info : Serr);
{ os << "Invoking wmake libso " << this->codePath().c_str() << endl;
Info<< "Invoking wmake libso " << this->codePath().c_str() << endl;
}
else
{
// Even with details turned off, we want some feedback
Serr<< "Invoking wmake libso " << this->codePath().c_str() << endl;
}
if (Foam::system(cmd) == 0) if (Foam::system(cmd) == 0)
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -47,7 +47,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class dynamicCodeContext; class dynamicCodeContext;
class ISstream; class ISstream;
class OSstream; class OSstream;
@ -60,10 +60,12 @@ class SHA1Digest;
class dynamicCode class dynamicCode
{ {
public: public:
typedef Tuple2<fileName, string> fileAndContent; typedef Tuple2<fileName, string> fileAndContent;
private: private:
// Private data
// Private Data
//- Root for dynamic code compilation //- Root for dynamic code compilation
fileName codeRoot_; fileName codeRoot_;
@ -104,7 +106,7 @@ private:
protected: protected:
// Static data members // Static Data Members
//- Root of the LIB target for Make/files //- Root of the LIB target for Make/files
static const char* const libTargetRoot; static const char* const libTargetRoot;
@ -151,7 +153,7 @@ protected:
public: public:
// Static data members // Static Data Members
//- Name of the code template environment variable //- Name of the code template environment variable
// Used to located the codeTemplateName // Used to located the codeTemplateName
@ -170,15 +172,12 @@ public:
//- Check security for creating dynamic code //- Check security for creating dynamic code
static void checkSecurity(const char* title, const dictionary&); static void checkSecurity(const char* title, const dictionary&);
//- Return the library basename without leading 'lib' or trailing '.so'
static word libraryBaseName(const fileName& libPath);
// Constructors // Constructors
//- Construct for a specified code name and code directory name //- Construct for a specified code name and code directory name
// Defaults to using the code name for the code directory name // Defaults to using the code name for the code directory name
dynamicCode explicit dynamicCode
( (
const word& codeName, const word& codeName,
const word& codeDirName = "" const word& codeDirName = ""

View File

@ -83,7 +83,7 @@ Foam::autoPtr<Foam::functionObject> Foam::functionObject::New
if (finder.found()) if (finder.found())
{ {
const_cast<Time&>(runTime).libs().open runTime.libs().open
( (
dict, dict,
finder.ref().keyword(), finder.ref().keyword(),
@ -93,7 +93,7 @@ Foam::autoPtr<Foam::functionObject> Foam::functionObject::New
} }
// This is the simplified version without compatibility messages // This is the simplified version without compatibility messages
// const_cast<Time&>(runTime).libs().open // runTime.libs().open
// ( // (
// dict, // dict,
// "libs", // "libs",

View File

@ -771,7 +771,7 @@ bool Foam::functionObjectList::read()
addProfiling(fo, "functionObjects::read"); addProfiling(fo, "functionObjects::read");
const_cast<Time&>(time_).libs().open time_.libs().open
( (
functionsDict, functionsDict,
"libs", "libs",

View File

@ -66,7 +66,7 @@ const
template<class Type> template<class Type>
Foam::dlLibraryTable& Foam::codedFixedValuePointPatchField<Type>::libs() const Foam::dlLibraryTable& Foam::codedFixedValuePointPatchField<Type>::libs() const
{ {
return const_cast<dlLibraryTable&>(this->db().time().libs()); return this->db().time().libs();
} }

View File

@ -106,7 +106,7 @@ class codedFixedValuePointPatchField
public fixedValuePointPatchField<Type>, public fixedValuePointPatchField<Type>,
protected codedBase protected codedBase
{ {
// Private data // Private Data
//- Dictionary contents for the boundary condition //- Dictionary contents for the boundary condition
mutable dictionary dict_; mutable dictionary dict_;
@ -120,7 +120,7 @@ class codedFixedValuePointPatchField
const IOdictionary& dict() const; const IOdictionary& dict() const;
//- Get the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object

View File

@ -854,8 +854,8 @@ Foam::argList::argList
if (strcmp(optName, "lib") == 0) if (strcmp(optName, "lib") == 0)
{ {
// The '-lib' option: // The '-lib' option:
// Append name(s) to libs_ for later opening // Append name(s) to libs for later opening
libs_.append(this->getList<fileName>(argi)); libs().append(this->getList<fileName>(argi));
} }
else if (strcmp(optName, "debug-switch") == 0) else if (strcmp(optName, "debug-switch") == 0)
{ {
@ -1066,8 +1066,8 @@ void Foam::argList::parse
jobInfo.add("foamBuild", build); jobInfo.add("foamBuild", build);
} }
// Load additional libraries // Load additional libraries (verbosity according to banner setting)
libs_.open(bannerEnabled()); libs().open(bannerEnabled());
} }
@ -1253,7 +1253,7 @@ void Foam::argList::parse
// Disable any parallel comms happening inside the fileHandler // Disable any parallel comms happening inside the fileHandler
// since we are on master. This can happen e.g. inside // since we are on master. This can happen e.g. inside
// the masterUncollated/collated handler. // the masterUncollated/collated handler.
const bool oldParRun = Pstream::parRun(); const bool oldParRun = Pstream::parRun();
Pstream::parRun() = false; Pstream::parRun() = false;

View File

@ -142,7 +142,7 @@ class argList
HashTable<string> options_; HashTable<string> options_;
//- Additional libraries //- Additional libraries
dlLibraryTable libs_; mutable dlLibraryTable libs_;
word executable_; word executable_;
fileName rootPath_; fileName rootPath_;
@ -346,11 +346,8 @@ public:
//- Return the ParRunControl //- Return the ParRunControl
inline const ParRunControl& parRunControl() const; inline const ParRunControl& parRunControl() const;
//- Access to the loaded libraries //- Mutable access to the loaded dynamic libraries
inline const dlLibraryTable& libs() const; inline dlLibraryTable& libs() const;
//- Access to the loaded libraries
inline dlLibraryTable& libs();
//- The number of arguments //- The number of arguments
inline label size() const noexcept; inline label size() const noexcept;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -112,13 +112,7 @@ inline const Foam::ParRunControl& Foam::argList::parRunControl() const
} }
inline const Foam::dlLibraryTable& Foam::argList::libs() const inline Foam::dlLibraryTable& Foam::argList::libs() const
{
return libs_;
}
inline Foam::dlLibraryTable& Foam::argList::libs()
{ {
return libs_; return libs_;
} }

View File

@ -308,7 +308,7 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
controlDict.getOrDefault<word>("agglomerator", "faceAreaPair") controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
); );
const_cast<Time&>(mesh.thisDb().time()).libs().open mesh.thisDb().time().libs().open
( (
controlDict, controlDict,
"geometricGAMGAgglomerationLibs", "geometricGAMGAgglomerationLibs",
@ -362,7 +362,7 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
controlDict.getOrDefault<word>("agglomerator", "faceAreaPair") controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
); );
const_cast<Time&>(mesh.thisDb().time()).libs().open mesh.thisDb().time().libs().open
( (
controlDict, controlDict,
"algebraicGAMGAgglomerationLibs", "algebraicGAMGAgglomerationLibs",
@ -408,7 +408,7 @@ Foam::autoPtr<Foam::GAMGAgglomeration> Foam::GAMGAgglomeration::New
controlDict.getOrDefault<word>("agglomerator", "faceAreaPair") controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
); );
const_cast<Time&>(mesh.thisDb().time()).libs().open mesh.thisDb().time().libs().open
( (
controlDict, controlDict,
"geometricGAMGAgglomerationLibs", "geometricGAMGAgglomerationLibs",

View File

@ -58,7 +58,7 @@ Foam::autoPtr<Foam::dynamicFvMesh> Foam::dynamicFvMesh::New(const IOobject& io)
Info<< "Selecting dynamicFvMesh " << modelType << endl; Info<< "Selecting dynamicFvMesh " << modelType << endl;
const_cast<Time&>(io.time()).libs().open io.time().libs().open
( (
dict, dict,
"dynamicFvMeshLibs", "dynamicFvMeshLibs",

View File

@ -89,7 +89,7 @@ void Foam::codedPoints0MotionSolver::prepare
Foam::dlLibraryTable& Foam::codedPoints0MotionSolver::libs() const Foam::dlLibraryTable& Foam::codedPoints0MotionSolver::libs() const
{ {
return const_cast<Time&>(mesh().time()).libs(); return mesh().time().libs();
} }

View File

@ -103,7 +103,7 @@ protected:
// Protected Member Functions // Protected Member Functions
//- Get the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object

View File

@ -94,7 +94,7 @@ Foam::displacementMotionSolver::New
{ {
Info<< "Selecting motion solver: " << solverTypeName << endl; Info<< "Selecting motion solver: " << solverTypeName << endl;
const_cast<Time&>(mesh.time()).libs().open mesh.time().libs().open
( (
solverDict, solverDict,
"motionSolverLibs", "motionSolverLibs",

View File

@ -116,7 +116,7 @@ Foam::autoPtr<Foam::motionSolver> Foam::motionSolver::New
Info<< "Selecting motion solver: " << solverName << nl; Info<< "Selecting motion solver: " << solverName << nl;
const_cast<Time&>(mesh.time()).libs().open mesh.time().libs().open
( (
solverDict, solverDict,
"motionSolverLibs", "motionSolverLibs",

View File

@ -79,7 +79,7 @@ Foam::autoPtr<Foam::fv::option> Foam::fv::option::New
Info<< indent Info<< indent
<< "Selecting finite volume options type " << modelType << endl; << "Selecting finite volume options type " << modelType << endl;
const_cast<Time&>(mesh.time()).libs().open mesh.time().libs().open
( (
coeffs, coeffs,
"libs", "libs",

View File

@ -112,7 +112,6 @@ Foam::expressions::fvExprDriver::fvExprDriver
storedVariables_(), storedVariables_(),
specialVariablesIndex_(-1), specialVariablesIndex_(-1),
otherMeshName_(), otherMeshName_(),
libs_(),
writer_(nullptr) writer_(nullptr)
{} {}
@ -128,7 +127,6 @@ Foam::expressions::fvExprDriver::fvExprDriver
storedVariables_(rhs.storedVariables_), storedVariables_(rhs.storedVariables_),
specialVariablesIndex_(rhs.specialVariablesIndex_), specialVariablesIndex_(rhs.specialVariablesIndex_),
otherMeshName_(), otherMeshName_(),
libs_(),
writer_(nullptr) writer_(nullptr)
{} {}
@ -165,12 +163,15 @@ bool Foam::expressions::fvExprDriver::readDict
{ {
expressions::exprDriver::readDict(dict); expressions::exprDriver::readDict(dict);
// wordList plugins; // fileNameList plugins;
// if (dict.readIfPresent("functionPlugins", plugins)) // if (dict.readIfPresent("functionPlugins", plugins))
// { // {
// for (const word& plugin : plugins) // for (const fileName& libName : plugins)
// { // {
// libs_.open("libswak" + plugin + "FunctionPlugin.so"); // this->runTime().libs().open
// (
// "libswak" + libName + "FunctionPlugin" // verbose = true
// );
// } // }
// } // }

View File

@ -69,7 +69,6 @@ SourceFiles
#include "pointMesh.H" #include "pointMesh.H"
#include "volFields.H" #include "volFields.H"
#include "topoSetSource.H" #include "topoSetSource.H"
#include "dlLibraryTable.H"
#include "runTimeSelectionTables.H" #include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -118,9 +117,6 @@ class fvExprDriver
//- The name of the other mesh (if it is to be required) //- The name of the other mesh (if it is to be required)
word otherMeshName_; word otherMeshName_;
//- Additional libraries
dlLibraryTable libs_;
//- Writing and restoring //- Writing and restoring
autoPtr<exprDriverWriter> writer_; autoPtr<exprDriverWriter> writer_;

View File

@ -66,7 +66,7 @@ const Foam::IOdictionary& Foam::codedFixedValueFvPatchField<Type>::dict() const
template<class Type> template<class Type>
Foam::dlLibraryTable& Foam::codedFixedValueFvPatchField<Type>::libs() const Foam::dlLibraryTable& Foam::codedFixedValueFvPatchField<Type>::libs() const
{ {
return const_cast<dlLibraryTable&>(this->db().time().libs()); return this->db().time().libs();
} }

View File

@ -121,7 +121,7 @@ class codedFixedValueFvPatchField
const IOdictionary& dict() const; const IOdictionary& dict() const;
//- Get the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object

View File

@ -65,7 +65,7 @@ const Foam::IOdictionary& Foam::codedMixedFvPatchField<Type>::dict() const
template<class Type> template<class Type>
Foam::dlLibraryTable& Foam::codedMixedFvPatchField<Type>::libs() const Foam::dlLibraryTable& Foam::codedMixedFvPatchField<Type>::libs() const
{ {
return const_cast<dlLibraryTable&>(this->db().time().libs()); return this->db().time().libs();
} }

View File

@ -104,7 +104,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of classes // Forward Declarations
class dynamicCode; class dynamicCode;
class dynamicCodeContext; class dynamicCodeContext;
class IOdictionary; class IOdictionary;
@ -119,7 +119,7 @@ class codedMixedFvPatchField
public mixedFvPatchField<Type>, public mixedFvPatchField<Type>,
public codedBase public codedBase
{ {
// Private data // Private Data
//- Dictionary contents for the boundary condition //- Dictionary contents for the boundary condition
mutable dictionary dict_; mutable dictionary dict_;
@ -133,7 +133,12 @@ class codedMixedFvPatchField
const IOdictionary& dict() const; const IOdictionary& dict() const;
//- Get the loaded dynamic libraries
protected:
// Protected Member Functions
//- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object

View File

@ -96,7 +96,7 @@ void Foam::functionObjects::codedFunctionObject::prepare
Foam::dlLibraryTable& Foam::functionObjects::codedFunctionObject::libs() const Foam::dlLibraryTable& Foam::functionObjects::codedFunctionObject::libs() const
{ {
return const_cast<Time&>(time_).libs(); return time_.libs();
} }

View File

@ -60,6 +60,7 @@ Usage
#{ #{
// Lookup U // Lookup U
const volVectorField& U = mesh().lookupObject<volVectorField>("U"); const volVectorField& U = mesh().lookupObject<volVectorField>("U");
// Write // Write
mag(U)().write(); mag(U)().write();
#}; #};
@ -99,7 +100,7 @@ class codedFunctionObject
{ {
protected: protected:
// Protected data // Protected Data
//- Input dictionary //- Input dictionary
dictionary dict_; dictionary dict_;
@ -118,7 +119,7 @@ protected:
// Protected Member Functions // Protected Member Functions
//- Get the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object

View File

@ -87,7 +87,7 @@ void Foam::fv::CodedSource<Type>::prepare
template<class Type> template<class Type>
Foam::dlLibraryTable& Foam::fv::CodedSource<Type>::libs() const Foam::dlLibraryTable& Foam::fv::CodedSource<Type>::libs() const
{ {
return const_cast<Time&>(mesh_.time()).libs(); return mesh_.time().libs();
} }

View File

@ -126,7 +126,6 @@ class CodedSource
public cellSetOption, public cellSetOption,
protected codedBase protected codedBase
{ {
protected: protected:
// Protected Data // Protected Data
@ -143,7 +142,7 @@ protected:
// Protected Member Functions // Protected Member Functions
//- Get the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object

View File

@ -27,16 +27,13 @@ License
#include "dynamicCode.H" #include "dynamicCode.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type> template<class Type>
Foam::dlLibraryTable& Foam::dlLibraryTable&
Foam::PatchFunction1Types::CodedField<Type>::libs() const Foam::PatchFunction1Types::CodedField<Type>::libs() const
{ {
const dlLibraryTable& timeLibs = return this->patch_.boundaryMesh().mesh().time().libs();
this->patch_.boundaryMesh().mesh().time().libs();
return const_cast<dlLibraryTable&>(timeLibs);
} }

View File

@ -88,7 +88,7 @@ namespace PatchFunction1Types
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class CodedField Declaration Class CodedField Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class Type> template<class Type>
@ -109,7 +109,15 @@ class CodedField
// Private Member Functions // Private Member Functions
//- Get the loaded dynamic libraries //- Get reference to the underlying Function1
const PatchFunction1<Type>& redirectFunction() const;
protected:
// Protected Member Functions
//- Mutable access to the loaded dynamic libraries
virtual dlLibraryTable& libs() const; virtual dlLibraryTable& libs() const;
//- Adapt the context for the current object //- Adapt the context for the current object
@ -121,9 +129,6 @@ class CodedField
// Clear the ptr to the redirected object // Clear the ptr to the redirected object
virtual void clearRedirect() const; virtual void clearRedirect() const;
//- Get reference to the underlying Function1
const PatchFunction1<Type>& redirectFunction() const;
// Get the (sub)dictionary to initialize the codeContext // Get the (sub)dictionary to initialize the codeContext
virtual const dictionary& codeDict(const dictionary& fullDict) const; virtual const dictionary& codeDict(const dictionary& fullDict) const;