diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C index 56169d52a3eef4a0cc09a978ea34f312918faca8..41c3ea78c573d4c5722bb5c5c86f400b89606d0e 100644 --- a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C @@ -115,25 +115,9 @@ void* Foam::codedBase::loadLibrary // Manual execution of code after loading. // This is mandatory for codedBase. - void* rawSymbol = dlSymFind(handle, funcName); + const bool ok = libs().loadHook(handle, funcName, false); - if (rawSymbol) - { - 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 + if (!ok) { FatalIOErrorInFunction(context.dict()) << "Failed symbol lookup " << funcName.c_str() << nl @@ -175,23 +159,13 @@ void Foam::codedBase::unloadLibrary // Manual execution of code before unloading. // 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); - - if (fun) - { - (*fun)(false); // force unload - } - else - { - FatalIOErrorInFunction(context.dict()) - << "Failed symbol lookup " << funcName.c_str() << nl - << "from " << libPath << nl - << exit(FatalIOError); - } + IOWarningInFunction(context.dict()) + << "Failed looking up symbol " << funcName << nl + << "from " << libPath << nl; } if (!libs().close(libPath, false)) diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H index 48343e5276ae4f9001500389ed0e1069ea4eee1b..84db305a71969421f40daff03487a6c2808f99b9 100644 --- a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H @@ -75,13 +75,6 @@ class codedBase 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 //- Load specified library and execute funcName(true) diff --git a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C index da0979a6f64641f212bfb59067437ff76f2a8421..5242406173c3076c03bb25a487c2353116c2465d 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C +++ b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C @@ -27,10 +27,15 @@ License \*---------------------------------------------------------------------------*/ #include "dlLibraryTable.H" +#include "dynamicCode.H" #include "OSspecific.H" #include "IOstreams.H" #include "int.H" +// #undef Foam_exptl_dlLibraryLoaderHooks +#define Foam_exptl_dlLibraryLoaderHooks + + // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam @@ -41,6 +46,58 @@ namespace Foam // * * * * * * * * * * * * * 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 ( const fileName& libName, @@ -146,6 +203,16 @@ void Foam::dlLibraryTable::clear(bool verbose) 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)) { DebugInFunction @@ -242,6 +309,16 @@ bool Foam::dlLibraryTable::open(bool verbose) { ++nOpen; 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 { @@ -316,6 +393,16 @@ bool Foam::dlLibraryTable::close << "Closing " << libName << " 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]); libPtrs_[index] = nullptr; diff --git a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H index 26b5c57e857cd5805938b15b5faaaa069c2cb509..4e26e1a157027585b0f71494763aa58723ccf7ea 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H +++ b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H @@ -45,6 +45,9 @@ SourceFiles namespace Foam { +// Forward Declarations +class codedBase; + /*---------------------------------------------------------------------------*\ Class dlLibraryTable Declaration \*---------------------------------------------------------------------------*/ @@ -58,7 +61,65 @@ class dlLibraryTable 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. // Warning messages, but no additional side-effects.