From 2811c05444d7411e2db9c47599cbc716e2850b4b Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Tue, 15 Dec 2020 18:00:53 +0100 Subject: [PATCH] ENH: lazier handling of dynamic libraries - previously always called dlclose on opened libraries when destroying the dlLibraryTable. However, by force closing the libraries the situation can arise that the library is missing its own code that it needs on unload (#1524). This is also sometimes evident when closing VTK libraries for runTimePostProcessing (#354, #1585). - The new default is to not forcibly dlclose any libraries, unless the dlcloseOnTerminate OptimisationSwitch specifies otherwise. - The dlLibraryTable::close() method can be used to explicitly close all libraries and clear the list. - The dlLibraryTable::clear() method now only clears the entries, without a dlclose. --- etc/controlDict | 5 +++++ .../dlLibraryTable/dlLibraryTable.C | 20 +++++++++++++++++-- .../dlLibraryTable/dlLibraryTable.H | 16 +++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/etc/controlDict b/etc/controlDict index 1bacba34532..d928d90a748 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -140,6 +140,11 @@ OptimisationSwitches // Force dumping (at next timestep) upon signal (-1 to disable) and exit stopAtWriteNowSignal -1; + //- Use dlclose() when clearing the dlLibraryTable. + // This is presumably cleaner, but can also remove functions + // that are still needed (eg, to terminate the library itself) + dlcloseOnTerminate 0; + //- Choose STL ASCII parser: 0=Flex, 1=Ragel, 2=Manual fileFormats::stl 0; diff --git a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C index 54b3feca21b..9a5ad023d9f 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C +++ b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.C @@ -46,6 +46,12 @@ namespace Foam defineTypeNameAndDebug(dlLibraryTable, 0); } +int Foam::dlLibraryTable::dlcloseOnTerminate +( + Foam::debug::optimisationSwitch("dlcloseOnTerminate", 0) +); + + std::unique_ptr<Foam::dlLibraryTable> Foam::dlLibraryTable::global_(nullptr); @@ -238,7 +244,10 @@ Foam::dlLibraryTable::dlLibraryTable Foam::dlLibraryTable::~dlLibraryTable() { - clear(); + if (dlLibraryTable::dlcloseOnTerminate) + { + close(); + } } @@ -274,6 +283,13 @@ Foam::label Foam::dlLibraryTable::size() const } +void Foam::dlLibraryTable::clear() +{ + libPtrs_.clear(); + libNames_.clear(); +} + + Foam::List<Foam::fileName> Foam::dlLibraryTable::loaded() const { List<fileName> list(libNames_.size()); @@ -298,7 +314,7 @@ Foam::List<Foam::fileName> Foam::dlLibraryTable::loaded() const } -void Foam::dlLibraryTable::clear(bool verbose) +void Foam::dlLibraryTable::close(bool verbose) { label nLoaded = 0; diff --git a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H index a89df8f9085..8fa2f99a024 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H +++ b/src/OpenFOAM/db/dynamicLibrary/dlLibraryTable/dlLibraryTable.H @@ -99,6 +99,14 @@ class dlLibraryTable public: + // Static Data Members + + //- Use dlclose() when clearing the dlLibraryTable. + // This is presumably \em cleaner, but can also remove functions + // that are still needed (eg, to terminate the library itself) + static int dlcloseOnTerminate; + + // Public Data Types //- Global loader/unloader function type (C-linkage) @@ -229,8 +237,8 @@ public: return libPtrs_; } - //- Clearing closes all libraries loaded by the table. - void clear(bool verbose = true); + //- Clears the table, without attempting to close the libraries + void clear(); //- Add to the list of names, but do not yet open. // Ignores duplicate names. @@ -261,6 +269,10 @@ public: bool verbose = true ); + //- Close all libraries loaded by the table and remove the closed + //- functions from the table. + void close(bool verbose = true); + //- 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); -- GitLab