ENH: dlLibraryTable: moved library handles to objects

This commit is contained in:
mattijs 2011-04-18 16:41:21 +01:00
parent 804b801458
commit a791316896
14 changed files with 239 additions and 160 deletions

View File

@ -257,7 +257,7 @@ Foam::Time::Time
graphFormat_("raw"),
runTimeModifiable_(true),
readLibs_(controlDict_, "libs"),
libs_(controlDict_, "libs"),
functionObjects_(*this)
{
// Explicitly set read flags on objectRegistry so anything constructed
@ -343,7 +343,7 @@ Foam::Time::Time
graphFormat_("raw"),
runTimeModifiable_(true),
readLibs_(controlDict_, "libs"),
libs_(controlDict_, "libs"),
functionObjects_(*this)
{
// Explicitly set read flags on objectRegistry so anything constructed
@ -430,7 +430,7 @@ Foam::Time::Time
graphFormat_("raw"),
runTimeModifiable_(true),
readLibs_(controlDict_, "libs"),
libs_(controlDict_, "libs"),
functionObjects_(*this)
{}

View File

@ -166,8 +166,8 @@ private:
//- Is runtime modification of dictionaries allowed?
Switch runTimeModifiable_;
//- Instantiate a dummy class to cause the reading of dynamic libraries
dlLibraryTable::readDlLibrary readLibs_;
//- Any loaded dynamic libraries
dlLibraryTable libs_;
//- Function objects executed at start and on ++, +=
mutable functionObjectList functionObjects_;
@ -375,6 +375,12 @@ public:
return functionObjects_;
}
//- External access to the loaded libraries
dlLibraryTable& libs()
{
return libs_;
}
//- Return true if time currently being sub-cycled, otherwise false
bool subCycling() const
{

View File

@ -36,6 +36,7 @@ License
#include "Time.H"
#include "PstreamReduceOps.H"
#include "long.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -61,6 +62,36 @@ const Foam::word Foam::functionEntries::codeStream::codeTemplateC
= "codeStreamTemplate.C";
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
const Foam::dictionary& Foam::functionEntries::codeStream::topDict
(
const dictionary& dict
)
{
const dictionary& p = dict.parent();
if (&p != &dict && !p.name().empty())
{
return topDict(p);
}
else
{
return dict;
}
}
Foam::dlLibraryTable& Foam::functionEntries::codeStream::libs
(
const dictionary& dict
)
{
const IOdictionary& d = static_cast<const IOdictionary&>(topDict(dict));
return const_cast<Time&>(d.time()).libs();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionEntries::codeStream::execute
@ -99,8 +130,15 @@ bool Foam::functionEntries::codeStream::execute
const fileName libPath = dynCode.libPath();
// see if library is loaded
void* lib = dlLibraryTable::findLibrary(libPath);
void* lib = NULL;
if
(
isA<IOdictionary>(topDict(parentDict))
&& parentDict.dictName() != Time::controlDictName
)
{
lib = libs(parentDict).findLibrary(libPath);
}
if (!lib)
{
@ -110,9 +148,27 @@ bool Foam::functionEntries::codeStream::execute
// nothing loaded
// avoid compilation if possible by loading an existing library
if (!lib && dlLibraryTable::open(libPath, false))
if (!lib)
{
lib = dlLibraryTable::findLibrary(libPath);
if
(
isA<IOdictionary>(topDict(parentDict))
&& parentDict.dictName() != Time::controlDictName
)
{
// Cached access to dl libs. Guarantees clean up upon destruction
// of Time.
dlLibraryTable& dlLibs = libs(parentDict);
if (dlLibs.open(libPath, false))
{
lib = dlLibs.findLibrary(libPath);
}
}
else
{
// Uncached opening of libPath
lib = dlOpen(libPath);
}
}
@ -167,19 +223,34 @@ bool Foam::functionEntries::codeStream::execute
// all processes must wait for compile to finish
reduce(create, orOp<bool>());
if (!dlLibraryTable::open(libPath, false))
if
(
isA<IOdictionary>(topDict(parentDict))
&& parentDict.dictName() != Time::controlDictName
)
{
FatalIOErrorIn
(
"functionEntries::codeStream::execute(..)",
parentDict
) << "Failed loading library " << libPath << nl
<< "Did you add all libraries to the 'libs' entry"
<< " in system/controlDict?"
<< exit(FatalIOError);
}
// Cached access to dl libs. Guarantees clean up upon destruction
// of Time.
dlLibraryTable& dlLibs = libs(parentDict);
if (!dlLibs.open(libPath, false))
{
FatalIOErrorIn
(
"functionEntries::codeStream::execute(..)",
parentDict
) << "Failed loading library " << libPath << nl
<< "Did you add all libraries to the 'libs' entry"
<< " in system/controlDict?"
<< exit(FatalIOError);
}
lib = dlLibraryTable::findLibrary(libPath);
lib = dlLibs.findLibrary(libPath);
}
else
{
// Uncached opening of libPath
lib = dlOpen(libPath);
}
}

View File

@ -98,6 +98,8 @@ SourceFiles
namespace Foam
{
class dlLibraryTable;
namespace functionEntries
{
@ -113,9 +115,14 @@ class codeStream
//- Interpreter function type
typedef void (*streamingFunctionType)(Ostream&, const dictionary&);
// Private Member Functions
//- Helper function: parent (of parent etc.) of dictionary up to the top
static const dictionary& topDict(const dictionary&);
//- Helper function: access to dlLibraryTable of Time
static dlLibraryTable& libs(const dictionary& dict);
//- Disallow default bitwise copy construct
codeStream(const codeStream&);

View File

@ -26,11 +26,6 @@ License
#include "dlLibraryTable.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::dlLibraryTable Foam::dlLibraryTable::loadedLibraries;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dlLibraryTable::dlLibraryTable()
@ -39,11 +34,13 @@ Foam::dlLibraryTable::dlLibraryTable()
{}
Foam::dlLibraryTable::readDlLibrary::readDlLibrary
Foam::dlLibraryTable::dlLibraryTable
(
const dictionary& dict,
const word& libsEntry
)
:
HashTable<fileName, void*, Hash<void*> >()
{
open(dict, libsEntry);
}
@ -91,14 +88,7 @@ bool Foam::dlLibraryTable::open
}
else
{
if (loadedLibraries.insert(functionLibPtr, functionLibName))
{
return true;
}
else
{
return false;
}
return insert(functionLibPtr, functionLibName);
}
}
else
@ -117,7 +107,7 @@ bool Foam::dlLibraryTable::close
void* libPtr = findLibrary(functionLibName);
if (libPtr)
{
loadedLibraries.erase(libPtr);
erase(libPtr);
if (!dlClose(libPtr))
{
@ -141,7 +131,7 @@ bool Foam::dlLibraryTable::close
void* Foam::dlLibraryTable::findLibrary(const fileName& functionLibName)
{
forAllConstIter(dlLibraryTable, loadedLibraries, iter)
forAllConstIter(dlLibraryTable, *this, iter)
{
if (iter() == functionLibName)
{

View File

@ -63,30 +63,15 @@ class dlLibraryTable
public:
// Static data members
//- Static data someStaticData
static dlLibraryTable loadedLibraries;
// Public classes
//- Class whose construction causes the reading of dynamic libraries
class readDlLibrary
{
public:
//- Read all the libraries listed in the 'libsEntry' entry in the
// given dictionary if present
readDlLibrary(const dictionary&, const word& libsEntry);
};
// Constructors
//- Construct null
dlLibraryTable();
//- Construct from dictionary and name of 'libs' entry giving
// the libraries to load
dlLibraryTable(const dictionary&, const word&);
//- Destructor
~dlLibraryTable();
@ -95,23 +80,23 @@ public:
// Member Functions
//- Open the named library, optionally with warnings if problems occur
static bool open(const fileName& name, const bool verbose = true);
bool open(const fileName& name, const bool verbose = true);
//- Close the named library, optionally with warnings if problems occur
static bool close(const fileName& name, const bool verbose = true);
bool close(const fileName& name, const bool verbose = true);
//- Find the handle of the named library
static void* findLibrary(const fileName& name);
void* findLibrary(const fileName& name);
//- Open all the libraries listed in the 'libsEntry' entry in the
// given dictionary if present
static bool open(const dictionary&, const word& libsEntry);
bool open(const dictionary&, const word& libsEntry);
//- Open all the libraries listed in the 'libsEntry' entry in the
// given dictionary if present and check the additions
// to the given constructor table
template<class TablePtr>
static bool open
bool open
(
const dictionary&,
const word& libsEntry,

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,6 +26,7 @@ License
#include "functionObject.H"
#include "dictionary.H"
#include "dlLibraryTable.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -57,7 +58,7 @@ Foam::autoPtr<Foam::functionObject> Foam::functionObject::New
Info<< "Selecting function " << functionType << endl;
}
dlLibraryTable::open
const_cast<Time&>(t).libs().open
(
functionDict,
"functionObjectLibs",

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -104,7 +104,7 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
{
const word agglomeratorType(controlDict.lookup("agglomerator"));
dlLibraryTable::open
const_cast<Time&>(mesh.thisDb().time()).libs().open
(
controlDict,
"geometricGAMGAgglomerationLibs",
@ -159,7 +159,7 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
{
const word agglomeratorType(controlDict.lookup("agglomerator"));
dlLibraryTable::open
const_cast<Time&>(mesh.thisDb().time()).libs().open
(
controlDict,
"algebraicGAMGAgglomerationLibs",

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -49,7 +49,7 @@ Foam::autoPtr<Foam::dynamicFvMesh> Foam::dynamicFvMesh::New(const IOobject& io)
Info<< "Selecting dynamicFvMesh " << dynamicFvMeshTypeName << endl;
dlLibraryTable::open
const_cast<Time&>(io.time()).libs().open
(
dict,
"dynamicFvMeshLibs",

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -79,7 +79,7 @@ Foam::autoPtr<Foam::motionSolver> Foam::motionSolver::New(const polyMesh& mesh)
Info<< "Selecting motion solver: " << solverTypeName << endl;
dlLibraryTable::open
const_cast<Time&>(mesh.time()).libs().open
(
solverDict,
"motionSolverLibs",

View File

@ -59,60 +59,66 @@ void* Foam::codedFixedValueFvPatchField<Type>::loadLibrary
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
)
) const
{
void* lib = 0;
// avoid compilation by loading an existing library
if (!libPath.empty() && dlLibraryTable::open(libPath, false))
if (!libPath.empty())
{
lib = dlLibraryTable::findLibrary(libPath);
dlLibraryTable& libs = const_cast<Time&>(this->db().time()).libs();
// verify the loaded version and unload if needed
if (lib)
if (libs.open(libPath, false))
{
// provision for manual execution of code after loading
if (dlSymFound(lib, globalFuncName))
{
loaderFunctionType function =
reinterpret_cast<loaderFunctionType>
(
dlSym(lib, globalFuncName)
);
lib = libs.findLibrary(libPath);
if (function)
// verify the loaded version and unload if needed
if (lib)
{
// provision for manual execution of code after loading
if (dlSymFound(lib, globalFuncName))
{
(*function)(true); // force load
loaderFunctionType function =
reinterpret_cast<loaderFunctionType>
(
dlSym(lib, globalFuncName)
);
if (function)
{
(*function)(true); // force load
}
else
{
FatalIOErrorIn
(
"codedFixedValueFvPatchField<Type>::"
"updateLibrary()",
contextDict
) << "Failed looking up symbol " << globalFuncName
<< nl << "from " << libPath << exit(FatalIOError);
}
}
else
{
FatalIOErrorIn
(
"codedFixedValueFvPatchField<Type>::updateLibrary()",
"codedFixedValueFvPatchField<Type>::loadLibrary()",
contextDict
) << "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
}
}
else
{
FatalIOErrorIn
(
"codedFixedValueFvPatchField<Type>::loadLibrary()",
contextDict
) << "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
lib = 0;
if (!dlLibraryTable::close(libPath, false))
{
FatalIOErrorIn
(
"codedFixedValueFvPatchField<Type>::loadLibrary()",
contextDict
) << "Failed unloading library "
<< libPath
<< exit(FatalIOError);
lib = 0;
if (!libs.close(libPath, false))
{
FatalIOErrorIn
(
"codedFixedValueFvPatchField<Type>::loadLibrary()",
contextDict
) << "Failed unloading library "
<< libPath
<< exit(FatalIOError);
}
}
}
}
@ -128,15 +134,19 @@ void Foam::codedFixedValueFvPatchField<Type>::unloadLibrary
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
)
) const
{
void* lib = 0;
if (!libPath.empty())
if (libPath.empty())
{
lib = dlLibraryTable::findLibrary(libPath);
return;
}
dlLibraryTable& libs = const_cast<Time&>(this->db().time()).libs();
lib = libs.findLibrary(libPath);
if (!lib)
{
return;
@ -166,7 +176,7 @@ void Foam::codedFixedValueFvPatchField<Type>::unloadLibrary
}
}
if (!dlLibraryTable::close(libPath, false))
if (!libs.close(libPath, false))
{
FatalIOErrorIn
(
@ -334,7 +344,7 @@ void Foam::codedFixedValueFvPatchField<Type>::updateLibrary() const
// the correct library was already loaded => we are done
if (dlLibraryTable::findLibrary(libPath))
if (const_cast<Time&>(this->db().time()).libs().findLibrary(libPath))
{
return;
}

View File

@ -130,20 +130,20 @@ class codedFixedValueFvPatchField
);
//- Load specified library and execute globalFuncName(true)
static void* loadLibrary
void* loadLibrary
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
);
) const;
//- Execute globalFuncName(false) and unload specified library
static void unloadLibrary
void unloadLibrary
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
);
) const;
//- Set the rewrite vars controlling the Type
static void setFieldTemplates(dynamicCode& dynCode);

View File

@ -54,60 +54,65 @@ void* Foam::codedFunctionObject::loadLibrary
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
)
) const
{
void* lib = 0;
// avoid compilation by loading an existing library
if (!libPath.empty() && dlLibraryTable::open(libPath, false))
if (!libPath.empty())
{
lib = dlLibraryTable::findLibrary(libPath);
dlLibraryTable& libs = const_cast<Time&>(time_).libs();
// verify the loaded version and unload if needed
if (lib)
if (libs.open(libPath, false))
{
// provision for manual execution of code after loading
if (dlSymFound(lib, globalFuncName))
{
loaderFunctionType function =
reinterpret_cast<loaderFunctionType>
(
dlSym(lib, globalFuncName)
);
lib = libs.findLibrary(libPath);
if (function)
// verify the loaded version and unload if needed
if (lib)
{
// provision for manual execution of code after loading
if (dlSymFound(lib, globalFuncName))
{
(*function)(true); // force load
loaderFunctionType function =
reinterpret_cast<loaderFunctionType>
(
dlSym(lib, globalFuncName)
);
if (function)
{
(*function)(true); // force load
}
else
{
FatalIOErrorIn
(
"codedFunctionObject::updateLibrary()",
contextDict
) << "Failed looking up symbol " << globalFuncName
<< nl << "from " << libPath << exit(FatalIOError);
}
}
else
{
FatalIOErrorIn
(
"codedFunctionObject::updateLibrary()",
"codedFunctionObject::loadLibrary()",
contextDict
) << "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
}
}
else
{
FatalIOErrorIn
(
"codedFunctionObject::loadLibrary()",
contextDict
) << "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
lib = 0;
if (!dlLibraryTable::close(libPath, false))
{
FatalIOErrorIn
(
"codedFunctionObject::loadLibrary()",
contextDict
) << "Failed unloading library "
<< libPath
<< exit(FatalIOError);
lib = 0;
if (!libs.close(libPath, false))
{
FatalIOErrorIn
(
"codedFunctionObject::loadLibrary()",
contextDict
) << "Failed unloading library "
<< libPath
<< exit(FatalIOError);
}
}
}
}
@ -122,15 +127,19 @@ void Foam::codedFunctionObject::unloadLibrary
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
)
) const
{
void* lib = 0;
if (!libPath.empty())
if (libPath.empty())
{
lib = dlLibraryTable::findLibrary(libPath);
return;
}
dlLibraryTable& libs = const_cast<Time&>(time_).libs();
lib = libs.findLibrary(libPath);
if (!lib)
{
return;
@ -160,7 +169,7 @@ void Foam::codedFunctionObject::unloadLibrary
}
}
if (!dlLibraryTable::close(libPath, false))
if (!libs.close(libPath, false))
{
FatalIOErrorIn
(
@ -274,7 +283,7 @@ void Foam::codedFunctionObject::updateLibrary() const
// the correct library was already loaded => we are done
if (dlLibraryTable::findLibrary(libPath))
if (const_cast<Time&>(time_).libs().findLibrary(libPath))
{
return;
}

View File

@ -88,20 +88,20 @@ protected:
typedef void (*loaderFunctionType)(bool);
//- Load specified library and execute globalFuncName(true)
static void* loadLibrary
void* loadLibrary
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
);
) const;
//- Execute globalFuncName(false) and unload specified library
static void unloadLibrary
void unloadLibrary
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
);
) const;
//- Create library based on the dynamicCodeContext