Compare commits

...

1 Commits

Author SHA1 Message Date
18dc3426ce WIP: code ideas for load/unload functions in dlLibraryTable 2019-12-16 16:30:05 +01:00
4 changed files with 156 additions and 41 deletions

View File

@ -115,25 +115,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
@ -175,23 +159,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))

View File

@ -75,13 +75,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)

View File

@ -27,10 +27,15 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "dlLibraryTable.H" #include "dlLibraryTable.H"
#include "dynamicCode.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "IOstreams.H" #include "IOstreams.H"
#include "int.H" #include "int.H"
// #undef Foam_exptl_dlLibraryLoaderHooks
#define Foam_exptl_dlLibraryLoaderHooks
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -41,6 +46,58 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
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;
// Manual execution of loader/unloader code
void* rawSymbol = dlSymFind(handle, funcName);
if (rawSymbol)
{
try
{
loaderType fun = reinterpret_cast<loaderType>(rawSymbol);
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;
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void* Foam::dlLibraryTable::openLibrary void* Foam::dlLibraryTable::openLibrary
( (
const fileName& libName, const fileName& libName,
@ -146,6 +203,16 @@ void Foam::dlLibraryTable::clear(bool verbose)
continue; continue;
} }
#ifdef Foam_exptl_dlLibraryLoaderHooks
// Attempt unload prior to close
unloadHook
(
libPtrs_[i],
dynamicCode::libraryBaseName(libNames_[i]),
debug // verbosity according to debug
);
#endif
if (Foam::dlClose(ptr)) if (Foam::dlClose(ptr))
{ {
DebugInFunction DebugInFunction
@ -242,6 +309,16 @@ bool Foam::dlLibraryTable::open(bool verbose)
{ {
++nOpen; ++nOpen;
libPtrs_[i] = ptr; libPtrs_[i] = ptr;
#ifdef Foam_exptl_dlLibraryLoaderHooks
// Attempt load immediately after open
loadHook
(
libPtrs_[i],
dynamicCode::libraryBaseName(libNames_[i]),
debug // verbosity according to debug
);
#endif
} }
else else
{ {
@ -316,6 +393,16 @@ bool Foam::dlLibraryTable::close
<< "Closing " << libName << "Closing " << libName
<< " with handle " << Foam::name(libPtrs_[index]) << nl; << " with handle " << Foam::name(libPtrs_[index]) << nl;
#ifdef Foam_exptl_dlLibraryLoaderHooks
// Attempt unload prior to close
unloadHook
(
libPtrs_[index],
dynamicCode::libraryBaseName(libNames_[index]),
debug // verbosity according to debug
);
#endif
const bool ok = Foam::dlClose(libPtrs_[index]); const bool ok = Foam::dlClose(libPtrs_[index]);
libPtrs_[index] = nullptr; libPtrs_[index] = nullptr;

View File

@ -45,6 +45,9 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class codedBase;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class dlLibraryTable Declaration Class dlLibraryTable Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -58,7 +61,65 @@ class dlLibraryTable
DynamicList<fileName> libNames_; DynamicList<fileName> libNames_;
// Private Member Functions protected:
// Data Types
//- Global loader/unloader function type
// Called with true on load, false on unload.
typedef void (*loaderType)(bool);
// Friends
//- Allow codedBase as a friend for the low-level hooks
friend class codedBase;
// Protected 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,
const std::string& funcName,
const bool verbose,
const std::string& context
);
// Static Member Functions
//- Execute global funcName(true) on the library (low-level interface).
// Usually done as 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 = ""
)
{
return functionHook(true, handle, funcName, verbose, context);
}
//- Execute global funcName(false) on the library (low-level interface).
// Usually done as 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 = ""
)
{
return functionHook(false, handle, funcName, verbose, 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.