From 74bc658fe98c57d7beeeab8bcf2ef7e789bb064e Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 24 Feb 2011 17:14:59 +0100 Subject: [PATCH] ENH: new encapsulation: dynamicCode, dynamicCodeContext - improve loading/unloading characteristics for codedFixedValue but still needs work --- src/OpenFOAM/Make/files | 3 +- .../functionEntries/codeStream/codeStream.C | 137 ++--- .../codeStream/codeStreamTools.C | 369 -------------- .../dynamicLibrary/dynamicCode/dynamicCode.C | 479 ++++++++++++++++++ .../dynamicCode.H} | 200 ++++---- .../dynamicCode/dynamicCodeContext.C | 69 +++ .../dynamicCode/dynamicCodeContext.H | 120 +++++ src/OpenFOAM/global/argList/argList.C | 4 +- .../codedFixedValueFvPatchScalarField.C | 273 +++++----- .../codedFixedValueFvPatchScalarField.H | 19 +- .../functionObjects/systemCall/systemCall.C | 4 +- 11 files changed, 946 insertions(+), 731 deletions(-) delete mode 100644 src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C create mode 100644 src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C rename src/OpenFOAM/db/dynamicLibrary/{codeStream/codeStreamTools.H => dynamicCode/dynamicCode.H} (51%) create mode 100644 src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C create mode 100644 src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 32112f8737..18522689e8 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -189,8 +189,9 @@ db/objectRegistry/objectRegistry.C db/CallbackRegistry/CallbackRegistryName.C dll = db/dynamicLibrary -$(dll)/codeStream/codeStreamTools.C $(dll)/dlLibraryTable/dlLibraryTable.C +$(dll)/dynamicCode/dynamicCode.C +$(dll)/dynamicCode/dynamicCodeContext.C db/functionObjects/functionObject/functionObject.C db/functionObjects/functionObjectList/functionObjectList.C diff --git a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C index 6144653367..da2b637979 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C @@ -28,10 +28,9 @@ License #include "IStringStream.H" #include "OStringStream.H" #include "IOstreams.H" -#include "SHA1Digest.H" -#include "OSHA1stream.H" -#include "codeStreamTools.H" #include "stringOps.H" +#include "dynamicCode.H" +#include "dynamicCodeContext.H" #include "dlLibraryTable.H" #include "OSspecific.H" #include "Time.H" @@ -71,7 +70,7 @@ bool Foam::functionEntries::codeStream::execute Istream& is ) { - codeStreamTools::checkSecurity + dynamicCode::checkSecurity ( "functionEntries::codeStream::execute(..)", parentDict @@ -81,54 +80,23 @@ bool Foam::functionEntries::codeStream::execute // must reference parent for stringOps::expand to work nicely dictionary codeDict("#codeStream", parentDict, is); + // get code, codeInclude, codeOptions + dynamicCodeContext context(codeDict); - // Read three sections of code. - // Remove any leading whitespace - necessary for compilation options, - // convenience for includes and body. - - // "codeInclude" is optional - string codeInclude; - if (codeDict.found("codeInclude")) - { - codeInclude = stringOps::trim(codeDict["codeInclude"]); - stringOps::inplaceExpand(codeInclude, codeDict); - } - - // "codeOptions" is optional - string codeOptions; - if (codeDict.found("codeOptions")) - { - codeOptions = stringOps::trim(codeDict["codeOptions"]); - stringOps::inplaceExpand(codeOptions, codeDict); - } - - // "code" is mandatory - string code = stringOps::trim(codeDict["code"]); - stringOps::inplaceExpand(code, codeDict); - - - // Create SHA1 digest from the contents - SHA1Digest sha; - { - OSHA1stream os; - os << codeInclude << codeOptions << code; - sha = os.digest(); - } - - - // codeName = prefix + sha1 - const fileName codeName = "codeStream_" + sha.str(); - - // write code into _SHA1 subdir - const fileName codePath = codeStreamTools::codePath("_" + sha.str()); - - // write library into platforms/$WM_OPTIONS/lib subdir - const fileName libPath = codeStreamTools::libPath(codeName); + // codeName: prefix_ + sha1 + // codeDir : _ + dynamicCode dynCode + ( + "codeStream_" + context.sha1().str(), + "_" + context.sha1().str() + ); + // Load library if not already loaded + // Version information is encoded in the libPath (encoded with the SHA1) + const fileName libPath = dynCode.libPath(); void* lib = dlLibraryTable::findLibrary(libPath); - // try to load if not already loaded if (!lib && dlLibraryTable::open(libPath, false)) { lib = dlLibraryTable::findLibrary(libPath); @@ -139,76 +107,54 @@ bool Foam::functionEntries::codeStream::execute { if (Pstream::master()) { - if (!codeStreamTools::upToDate(codePath, sha)) + if (!dynCode.upToDate(context)) { - Info<< "Creating new library in " << libPath << endl; + Info<< "Creating new library in " + << dynCode.libPath() << endl; - const fileName fileCsrc - ( - codeStreamTools::findTemplate - ( - codeTemplateC - ) - ); + // filter C template + dynCode.addFilterFile(codeTemplateC); - // not found! - if (fileCsrc.empty()) - { - FatalIOErrorIn - ( - "functionEntries::codeStream::execute(..)", - parentDict - ) << "Could not find the code template: " - << codeTemplateC << nl - << codeStreamTools::searchedLocations() - << exit(FatalIOError); - } - - - List copyFiles(1); - copyFiles[0].file() = fileCsrc; - copyFiles[0].set("codeInclude", codeInclude); - copyFiles[0].set("code", code); - copyFiles[0].set("SHA1sum", sha.str()); - - List filesContents(2); + // filter with this context + dynCode.setFilterContext(context); // Write Make/files - filesContents[0].first() = "Make/files"; - filesContents[0].second() = + dynCode.addCreateFile + ( + "Make/files", codeTemplateC + "\n\n" - + codeStreamTools::libTarget(codeName); + + dynCode.libTarget() + ); // Write Make/options - filesContents[1].first() = "Make/options"; - filesContents[1].second() = + dynCode.addCreateFile + ( + "Make/options", "EXE_INC = -g \\\n" - + codeOptions - + "\n\nLIB_LIBS ="; + + context.options() + + "\n\nLIB_LIBS =" + ); - codeStreamTools writer(codeName, copyFiles, filesContents); - if (!writer.copyFilesContents(codePath)) + if (!dynCode.copyFilesContents()) { FatalIOErrorIn ( "functionEntries::codeStream::execute(..)", parentDict - ) << "Failed writing " < ( - dlSym(lib, codeName) + dlSym(lib, dynCode.codeName()) ); + if (!function) { FatalIOErrorIn ( "functionEntries::codeStream::execute(..)", parentDict - ) << "Failed looking up symbol " << codeName + ) << "Failed looking up symbol " << dynCode.codeName() << " in library " << lib << exit(FatalIOError); } diff --git a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C b/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C deleted file mode 100644 index e29732ce8d..0000000000 --- a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.C +++ /dev/null @@ -1,369 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -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 2 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, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -\*---------------------------------------------------------------------------*/ - -#include "codeStreamTools.H" -#include "stringOps.H" -#include "IFstream.H" -#include "OFstream.H" -#include "OSspecific.H" -#include "dictionary.H" -#include "dlLibraryTable.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -int Foam::codeStreamTools::allowSystemOperations -( - Foam::debug::infoSwitch("allowSystemOperations", 0) -); - - -const Foam::word Foam::codeStreamTools::codeTemplateEnvName - = "FOAM_CODE_TEMPLATES"; - -const Foam::fileName Foam::codeStreamTools::codeTemplateDirName - = "codeTemplates/dynamicCode"; - - -// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // - -void Foam::codeStreamTools::checkSecurity -( - const char* title, - const dictionary& context -) -{ - if (isAdministrator()) - { - FatalIOErrorIn - ( - title, - context - ) << "This code should not be executed by someone with administrator" - << " rights due to security reasons." << nl - << "(it writes a shared library which then gets loaded " - << "using dlopen)" - << exit(FatalIOError); - } -} - - - -Foam::fileName Foam::codeStreamTools::codePath(const word& subDirName) -{ - return stringOps::expand("$FOAM_CASE/dynamicCode/" + subDirName); -} - - -Foam::fileName Foam::codeStreamTools::libPath(const word& codeName) -{ - return stringOps::expand - ( - "$FOAM_CASE/dynamicCode/platforms/$WM_OPTIONS/lib/lib" - + codeName + ".so" - ); -} - - -Foam::string Foam::codeStreamTools::libTarget(const word& codeName) -{ - return "LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib" + codeName; -} - - -Foam::fileName Foam::codeStreamTools::findTemplate(const word& templateFile) -{ - // try to get template from FOAM_CODE_TEMPLATES - fileName templateDir(Foam::getEnv(codeTemplateEnvName)); - - fileName file; - if (!templateDir.empty() && isDir(templateDir)) - { - file = templateDir/templateFile; - if (!isFile(file, false)) - { - file.clear(); - } - } - - // not found - fallback to ~OpenFOAM expansion - if (file.empty()) - { - file = findEtcFile(codeTemplateDirName/templateFile); - } - - return file; -} - - -Foam::string Foam::codeStreamTools::searchedLocations() -{ - return - ( - "Under the $" - + codeTemplateDirName - + " directory or via via the ~OpenFOAM/" - + codeTemplateDirName - + " expansion" - ); -} - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -void Foam::codeStreamTools::copyAndExpand -( - ISstream& is, - OSstream& os, - const HashTable& mapping -) const -{ - if (!is.good()) - { - FatalErrorIn - ( - "codeStreamTools::copyAndExpand()" - " const" - ) << "Failed opening for reading " << is.name() - << exit(FatalError); - } - - if (!os.good()) - { - FatalErrorIn - ( - "codeStreamTools::copyAndExpand()" - " const" - ) << "Failed writing " << os.name() - << exit(FatalError); - } - - // Copy file while rewriting $VARS and ${VARS} - string line; - do - { - is.getLine(line); - - // expand according to mapping - // expanding according to env variables might cause too many - // surprises - stringOps::inplaceExpand(line, mapping); - - os << line.c_str() << nl; - } - while (is.good()); -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::codeStreamTools::codeStreamTools() -{} - - -Foam::codeStreamTools::codeStreamTools -( - const word& name, - const dictionary& dict -) -: - name_(name) -{ - read(dict); -} - - -Foam::codeStreamTools::codeStreamTools -( - const word& name, - const List& copyFiles, - const List& filesContents -) -: - name_(name), - copyFiles_(copyFiles), - filesContents_(filesContents) -{} - - -Foam::codeStreamTools::codeStreamTools(const codeStreamTools& tools) -: - name_(tools.name_), - copyFiles_(tools.copyFiles_), - filesContents_(tools.filesContents_) -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -bool Foam::codeStreamTools::copyFilesContents(const fileName& dir) const -{ - if (!allowSystemOperations) - { - FatalErrorIn - ( - "codeStreamTools::copyFilesContents(const fileName&) const" - ) << "Loading a shared library using case-supplied code is not" - << " enabled by default" << nl - << "because of security issues. If you trust the code you can" - << " enable this" << nl - << "facility be adding to the InfoSwitches setting in the system" - << " controlDict:" << nl << nl - << " allowSystemOperations 1" << nl << nl - << "The system controlDict is either" << nl << nl - << " ~/.OpenFOAM/$WM_PROJECT_VERSION/controlDict" << nl << nl - << "or" << nl << nl - << " $WM_PROJECT_DIR/etc/controlDict" << nl - << endl - << exit(FatalError); - } - - // Create dir - mkDir(dir); - - // Info<< "set mapping typeName=" << name_ << endl; - // Copy any template files - forAll(copyFiles_, i) - { - const fileName sourceFile(fileName(copyFiles_[i].file()).expand()); - const fileName destFile(dir/sourceFile.name()); - - IFstream is(sourceFile); - //Info<< "Reading from " << is.name() << endl; - if (!is.good()) - { - FatalErrorIn - ( - "codeStreamTools::copyFilesContents(const fileName&)" - " const" - ) << "Failed opening " << sourceFile << exit(FatalError); - } - - OFstream os(destFile); - //Info<< "Writing to " << destFile.name() << endl; - if (!os.good()) - { - FatalErrorIn - ( - "codeStreamTools::copyFilesContents(const fileName&)" - " const" - ) << "Failed writing " << destFile << exit(FatalError); - } - - // variables mapping - HashTable mapping(copyFiles_[i]); - mapping.set("typeName", name_); - - // provide a zero digest if not otherwise specified - if (!mapping.found("SHA1sum")) - { - mapping.insert("SHA1sum", SHA1Digest().str()); - } - - copyAndExpand(is, os, mapping); - } - - - // Files that are always written: - forAll(filesContents_, i) - { - const fileName dstFile - ( - fileName(dir/filesContents_[i].first()).expand() - ); - - mkDir(dstFile.path()); - OFstream os(dstFile); - //Info<< "Writing to " << filesContents_[i].first() << endl; - if (!os.good()) - { - FatalErrorIn - ( - "codeStreamTools::copyFilesContents()" - " const" - ) << "Failed writing " << dstFile << exit(FatalError); - } - os << filesContents_[i].second().c_str() << endl; - } - - return true; -} - - -bool Foam::codeStreamTools::writeDigest -( - const fileName& dir, - const SHA1Digest& sha1 -) -{ - OFstream os(dir/"SHA1Digest"); - os << sha1; - return os.good(); -} - - -Foam::SHA1Digest Foam::codeStreamTools::readDigest(const fileName& dir) -{ - IFstream is(dir/"SHA1Digest"); - return SHA1Digest(is); -} - - -bool Foam::codeStreamTools::upToDate -( - const fileName& dir, - const SHA1Digest& sha1 -) -{ - if (!exists(dir/"SHA1Digest") || readDigest(dir) != sha1) - { - writeDigest(dir, sha1); - return false; - } - else - { - return true; - } -} - - -bool Foam::codeStreamTools::read(const dictionary& dict) -{ - dict.lookup("copyFiles") >> copyFiles_; - dict.lookup("filesContents") >> filesContents_; - - return true; -} - - -void Foam::codeStreamTools::writeDict(Ostream& os) const -{ - os.writeKeyword("copyFiles") << copyFiles_ << token::END_STATEMENT << nl; - os.writeKeyword("filesContents") << filesContents_ << token::END_STATEMENT - << nl; -} - - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C new file mode 100644 index 0000000000..b4c52afbb0 --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C @@ -0,0 +1,479 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "dynamicCode.H" +#include "dynamicCodeContext.H" +#include "stringOps.H" +#include "IFstream.H" +#include "OFstream.H" +#include "OSspecific.H" +#include "dictionary.H" +#include "dlLibraryTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::dynamicCode::allowSystemOperations +( + Foam::debug::infoSwitch("allowSystemOperations", 0) +); + + +const Foam::word Foam::dynamicCode::codeTemplateEnvName + = "FOAM_CODE_TEMPLATES"; + +const Foam::fileName Foam::dynamicCode::codeTemplateDirName + = "codeTemplates/dynamicCode"; + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +void Foam::dynamicCode::checkSecurity +( + const char* title, + const dictionary& dict +) +{ + if (isAdministrator()) + { + FatalIOErrorIn + ( + title, + dict + ) << "This code should not be executed by someone with administrator" + << " rights due to security reasons." << nl + << "(it writes a shared library which then gets loaded " + << "using dlopen)" + << exit(FatalIOError); + } +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::dynamicCode::copyAndFilter +( + ISstream& is, + OSstream& os, + const HashTable& mapping +) const +{ + if (!is.good()) + { + FatalErrorIn + ( + "dynamicCode::copyAndFilter()" + " const" + ) << "Failed opening for reading " << is.name() + << exit(FatalError); + } + + if (!os.good()) + { + FatalErrorIn + ( + "dynamicCode::copyAndFilter()" + " const" + ) << "Failed writing " << os.name() + << exit(FatalError); + } + + // Copy file while rewriting $VARS and ${VARS} + string line; + do + { + is.getLine(line); + + // expand according to mapping + // expanding according to env variables might cause too many + // surprises + stringOps::inplaceExpand(line, mapping); + + os << line.c_str() << nl; + } + while (is.good()); +} + + +Foam::List +Foam::dynamicCode::resolveTemplates(const UList& names) +{ + // try to get template from FOAM_CODESTREAM_TEMPLATES + const fileName templateDir(Foam::getEnv(codeTemplateEnvName)); + + DynamicList badFiles(names.size()); + List resolved(names.size()); + + label nResolved = 0; + + forAll(names, fileI) + { + const fileName& templateName = names[fileI]; + + fileName file; + if (!templateDir.empty() && isDir(templateDir)) + { + file = templateDir/templateName; + if (!isFile(file, false)) + { + file.clear(); + } + } + + // not found - fallback to ~OpenFOAM expansion + if (file.empty()) + { + file = findEtcFile(codeTemplateDirName/templateName); + } + + if (file.empty()) + { + badFiles.append(templateName); + } + else + { + resolved[nResolved++] = file; + } + } + + resolved.setSize(nResolved); + + if (!badFiles.empty()) + { + FatalErrorIn + ( + "dynamicCode::resolveTemplates(..)" + ) << "Could not find the code template(s): " + << badFiles << nl + << "Under the $" << codeTemplateDirName + << " directory or via via the ~OpenFOAM/" + << codeTemplateDirName << " expansion" + << exit(FatalError); + } + + return resolved; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::dynamicCode::dynamicCode(const word& codeName) +: + codeName_(codeName), + codeDirName_(codeName) +{ + filterVars_.set("typeName", codeName_); + filterVars_.set("SHA1sum", SHA1Digest().str()); +} + +Foam::dynamicCode::dynamicCode(const word& codeName, const word& codeDirName) +: + codeName_(codeName), + codeDirName_(codeDirName) +{ + filterVars_.set("typeName", codeName_); + filterVars_.set("SHA1sum", SHA1Digest().str()); +} + + +// Foam::dynamicCode::dynamicCode(const dynamicCode& dc) +// : +// codeName_(dc.codeName_), +// copyFiles_(dc.copyFiles_), +// filesContents_(dc.filesContents_) +// {} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::dynamicCode::clear() +{ + filterVars_.clear(); + filterFiles_.clear(); + createFiles_.clear(); + filterVars_.set("typeName", codeName_); + filterVars_.set("SHA1sum", SHA1Digest().str()); +} + + + +void Foam::dynamicCode::addCreateFile +( + const fileName& name, + const string& contents +) +{ + createFiles_.append(fileAndContent(name, contents)); +} + + +void Foam::dynamicCode::addFilterFile +( + const fileName& name +) +{ + filterFiles_.append(name); +} + + +void Foam::dynamicCode::setFilterContext +( + const dynamicCodeContext& context +) +{ + filterVars_.set("code", context.code()); + filterVars_.set("codeInclude", context.include()); + filterVars_.set("SHA1sum", context.sha1().str()); +} + + +void Foam::dynamicCode::setFilterVariable +( + const word& key, + const string& value +) +{ + filterVars_.set(key, value); +} + + +Foam::fileName Foam::dynamicCode::codePath() const +{ + return stringOps::expand("$FOAM_CASE/dynamicCode/" + codeDirName_); +} + + +Foam::fileName Foam::dynamicCode::libPath() const +{ + return + ( + stringOps::expand + ( + "$FOAM_CASE/dynamicCode/platforms/$WM_OPTIONS/lib/lib" + ) + + codeName_ + ".so" + ); +} + + +Foam::string Foam::dynamicCode::libTarget() const +{ + return "LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/lib" + codeName_; +} + + + +bool Foam::dynamicCode::copyFilesContents() const +{ + if (!allowSystemOperations) + { + FatalErrorIn + ( + "dynamicCode::copyFilesContents(const fileName&) const" + ) << "Loading a shared library using case-supplied code is not" + << " enabled by default" << nl + << "because of security issues. If you trust the code you can" + << " enable this" << nl + << "facility be adding to the InfoSwitches setting in the system" + << " controlDict:" << nl << nl + << " allowSystemOperations 1" << nl << nl + << "The system controlDict is either" << nl << nl + << " ~/.OpenFOAM/$WM_PROJECT_VERSION/controlDict" << nl << nl + << "or" << nl << nl + << " $WM_PROJECT_DIR/etc/controlDict" << nl + << endl + << exit(FatalError); + } + + List resolvedFiles = resolveTemplates(filterFiles_); + + // Create dir + const fileName outputDir = this->codePath(); + + // Create dir + mkDir(outputDir); + + // Copy/filter files + forAll(resolvedFiles, fileI) + { + const fileName& srcFile = resolvedFiles[fileI]; + const fileName dstFile(outputDir/srcFile.name()); + + IFstream is(srcFile); + //Info<< "Reading from " << is.name() << endl; + if (!is.good()) + { + FatalErrorIn + ( + "dynamicCode::copyFilesContents(const fileName&)" + " const" + ) << "Failed opening " << srcFile + << exit(FatalError); + } + + OFstream os(dstFile); + //Info<< "Writing to " << dstFile.name() << endl; + if (!os.good()) + { + FatalErrorIn + ( + "dynamicCode::copyFilesContents(const fileName&)" + " const" + ) << "Failed writing " << dstFile + << exit(FatalError); + } + + // variables mapping + copyAndFilter(is, os, filterVars_); + } + + + // Create files: + forAll(createFiles_, fileI) + { + const fileName dstFile + ( + outputDir/stringOps::expand(createFiles_[fileI].first()) + ); + + mkDir(dstFile.path()); + OFstream os(dstFile); + //Info<< "Writing to " << createFiles_[fileI].first() << endl; + if (!os.good()) + { + FatalErrorIn + ( + "dynamicCode::copyFilesContents()" + " const" + ) << "Failed writing " << dstFile + << exit(FatalError); + } + os << createFiles_[fileI].second().c_str() << endl; + } + + return true; +} + + +bool Foam::dynamicCode::wmakeLibso() const +{ + const Foam::string wmakeCmd("wmake libso " + this->codePath()); + Info<< "Invoking " << wmakeCmd << endl; + + if (Foam::system(wmakeCmd)) + { + return false; + } + else + { + return true; + } +} + + +bool Foam::dynamicCode::writeDigest +( + const fileName& dirName, + const SHA1Digest& sha1 +) const +{ + mkDir(dirName); + OFstream os(dirName/"SHA1Digest"); + os << sha1; + return os.good(); +} + + +Foam::SHA1Digest Foam::dynamicCode::readDigest(const fileName& dirName) const +{ + IFstream is(dirName/"SHA1Digest"); + return SHA1Digest(is); +} + + +bool Foam::dynamicCode::upToDate(const SHA1Digest& sha1) const +{ + const fileName dirName = this->codePath(); + if (!exists(dirName/"SHA1Digest") || readDigest(dirName) != sha1) + { + writeDigest(dirName, sha1); + return false; + } + else + { + return true; + } +} + + +bool Foam::dynamicCode::upToDate(const dynamicCodeContext& context) const +{ + return upToDate(context.sha1()); +} + + +// bool Foam::dynamicCode::openLibrary() const +// { +// return dlLibraryTable::openLibrary(this->libPath(), false); +// } +// +// +// bool Foam::dynamicCode::closeLibrary() const +// { +// return dlLibraryTable::closeLibrary(this->libPath(), false); +// } +// +// +// void* Foam::dynamicCode::findLibrary() const +// { +// return dlLibraryTable::findLibrary(this->libPath()); +// } + + + +// bool Foam::dynamicCode::read(const dictionary& dict) +// { +// dict.lookup("createFiles") >> createFiles_; +// dict.lookup("filterFiles") >> filterFiles_; +// dict.lookup("filterVariables") >> filterVariables_; +// +// return true; +// } +// +// +// void Foam::dynamicCode::writeDict(Ostream& os) const +// { +// os.writeKeyword("createFiles") << createFiles_ +// << token::END_STATEMENT << nl; +// +// os.writeKeyword("filterFiles") << filterFiles_ +// << token::END_STATEMENT << nl; +// +// os.writeKeyword("filterVariables") << filterVariables_ +// << token::END_STATEMENT << nl; +// } + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H similarity index 51% rename from src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.H rename to src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H index 8df397cc15..d122486156 100644 --- a/src/OpenFOAM/db/dynamicLibrary/codeStream/codeStreamTools.H +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H @@ -23,23 +23,24 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - Foam::codeStreamTools + Foam::dynamicCode Description - Base for all things on-the-fly from dictionary + Tools for handling dynamic code compilation SourceFiles - codeStreamTools.C + dynamicCode.C \*---------------------------------------------------------------------------*/ -#ifndef codeStreamTools_H -#define codeStreamTools_H +#ifndef dynamicCode_H +#define dynamicCode_H #include "Tuple2.H" -#include "Pair.H" #include "SHA1Digest.H" #include "HashTable.H" +#include "DynamicList.H" +#include "dlLibraryTable.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -47,66 +48,58 @@ namespace Foam { // Forward declaration of classes +class dynamicCodeContext; class ISstream; class OSstream; /*---------------------------------------------------------------------------*\ - Class codeStreamTools Declaration + Class dynamicCode Declaration \*---------------------------------------------------------------------------*/ -class codeStreamTools +class dynamicCode { public: typedef Tuple2 fileAndContent; - //- Helper class for managing file and variables - class fileAndVars - : - public HashTable - { - // Private data - fileName file_; - - public: - //- Construct null - fileAndVars() - {} - - //- Return the file name - const fileName& file() const - { - return file_; - } - - //- Return the file name - fileName& file() - { - return file_; - } - }; - - private: // Private data - //- Name for underlying set - word name_; + //- Name for code + word codeName_; - //- Files to copy - List copyFiles_; + //- Name for code subdirectory + mutable word codeDirName_; + + //- Variables to use during filtering + HashTable filterVars_; //- Direct contents for files - List filesContents_; + DynamicList createFiles_; + + //- Files to copy and filter + DynamicList filterFiles_; + protected: - void copyAndExpand + void copyAndFilter ( ISstream&, OSstream&, const HashTable& mapping ) const; + //- Resolve code-templates via the codeTemplateEnvName + // alternatively in the codeTemplateDirName via Foam::findEtcFile + static List resolveTemplates + ( + const UList& names + ); + + + bool writeDigest(const fileName& dir, const SHA1Digest& sha1) const; + SHA1Digest readDigest(const fileName& dir) const; + public: // Static data members @@ -119,87 +112,94 @@ public: // Used when locating the codeTemplateName via Foam::findEtcFile static const fileName codeTemplateDirName; - static int allowSystemOperations; - // Constructors - - //- Construct null - codeStreamTools(); - - //- Construct from dictionary - codeStreamTools(const word& name, const dictionary& dict); - - //- Copy from components - codeStreamTools - ( - const word& name, - const List&, - const List& - ); - - //- Construct copy - codeStreamTools(const codeStreamTools&); - - - // Member functions + // Static Member functions //- Check security for creating dynamic code static void checkSecurity ( const char* title, - const dictionary& context + const dictionary& dict ); + + // Constructors + + //- Construct for a specified code name + dynamicCode(const word& codeName); + + //- Construct for a specified code name and directory name + dynamicCode(const word& codeName, const word& dirName); + + + // Member functions + + //- Return the code-name + const word& codeName() const + { + return codeName_; + } + + //- Return the code-dirname + const word& codeDirName() const + { + return codeDirName_; + } + + //- Clear variables and files + void clear(); + + + //- Add a file to create with its contents. Will not be filtered + void addCreateFile(const fileName& name, const string& contents); + + //- Add a file template name, which will be found and filtered + void addFilterFile(const fileName& name); + + //- Define filter variables for code, codeInclude, SHA1sum + void setFilterContext(const dynamicCodeContext&); + + //- Define a filter variable + void setFilterVariable(const word& key, const string& value); + + //- Local path for specified code name - // Expanded from \$FOAM_CASE/codeStream - static fileName codePath(const word& subDirName); + // Expanded from \$FOAM_CASE/dynamicCode/codeDirName + fileName codePath() const; //- Local library path for specified code name - // Expanded from \$FOAM_CASE/platforms/\$WM_OPTIONS/lib - static fileName libPath(const word& codeName); + // Expanded from \$FOAM_CASE/dynamicCode/platforms/\$WM_OPTIONS/lib + fileName libPath() const; //- The library target path for Make/files - static string libTarget(const word& codeName); + string libTarget() const; - //- Find a code-template via the codeTemplateEnvName - // alternatively in the codeTemplateDirName via Foam::findEtcFile - static fileName findTemplate(const word& templateName); + //- Verify if the copied code is up-to-date + bool upToDate(const dynamicCodeContext& context) const; - //- List searched locations in a format suitable for display an error - static string searchedLocations(); + //- Verify if the copied code is up-to-date + bool upToDate(const SHA1Digest& sha1) const; + //- Copy/create files prior to compilation + bool copyFilesContents() const; + //- Compile a libso + bool wmakeLibso() const; - const word& name() const - { - return name_; - } +// //- Open the libPath() library +// bool openLibrary() const; +// +// //- Close the libPath() library +// bool closeLibrary() const; +// +// //- Find the handle of the libPath() library +// void* findLibrary() const; - const List& copyFiles() const - { - return copyFiles_; - } - - const List >& filesContents() const - { - return filesContents_; - } - - bool copyFilesContents(const fileName& dir) const; - - - static void* findLibrary(const fileName& libPath); - - static bool writeDigest(const fileName& dir, const SHA1Digest& sha1); - static SHA1Digest readDigest(const fileName& dir); - static bool upToDate(const fileName& dir, const SHA1Digest& sha1); - - bool read(const dictionary&); - - void writeDict(Ostream&) const; +// bool read(const dictionary&); +// void writeDict(Ostream&) const; }; diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C new file mode 100644 index 0000000000..44ca8f6fda --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C @@ -0,0 +1,69 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "dynamicCodeContext.H" +#include "stringOps.H" +#include "OSHA1stream.H" + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict) +: + dict_(dict), + code_(stringOps::trim(dict["code"])), + include_(), + options_() +{ + // expand dictionary entries + stringOps::inplaceExpand(code_, dict); + + // note: removes any leading/trailing whitespace + // - necessary for compilation options, convenient for includes + // and body. + + // optional + if (dict.found("codeInclude")) + { + include_ = stringOps::trim(dict["codeInclude"]); + stringOps::inplaceExpand(include_, dict); + } + + // optional + if (dict.found("codeOptions")) + { + options_ = stringOps::trim(dict["codeOptions"]); + stringOps::inplaceExpand(options_, dict); + } + + // calculate SHA1 digest from include, options, code + OSHA1stream os; + os << include_ << options_ << code_; + sha1_ = os.digest(); +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H new file mode 100644 index 0000000000..2aa248c20f --- /dev/null +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H @@ -0,0 +1,120 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::dynamicCodeContext + +Description + Encapsulation of dynamic code dictionaries + +SourceFiles + dynamicCodeContext.C + +\*---------------------------------------------------------------------------*/ + +#ifndef dynamicCodeContext_H +#define dynamicCodeContext_H + +#include "dictionary.H" +#include "SHA1Digest.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class dynamicCodeContext Declaration +\*---------------------------------------------------------------------------*/ + +class dynamicCodeContext +{ + // Private data + //- The parent dictionary context + const dictionary& dict_; + + //- Mandatory "code" entry + string code_; + + //- Optional "codeInclude" entry + string include_; + + //- Optional "codeOptions" entry + string options_; + + //- Calculated SHA1Digest + SHA1Digest sha1_; + +public: + + // Constructors + + //- Construct from a dictionary + dynamicCodeContext(const dictionary&); + + // Member functions + + //- Return the parent dictionary context + const dictionary& dict() const + { + return dict_; + } + + //- Return the code-includes + const string& include() const + { + return include_; + } + + //- Return the code-options + const string& options() const + { + return options_; + } + + //- Return the code + const string& code() const + { + return code_; + } + + //- Return SHA1 digest calculated from include, options, code + const SHA1Digest& sha1() const + { + return sha1_; + } + + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index 08cc78f762..f055011bce 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -32,7 +32,7 @@ License #include "JobInfo.H" #include "labelList.H" #include "regIOobject.H" -#include "codeStreamTools.H" +#include "dynamicCode.H" #include @@ -790,7 +790,7 @@ Foam::argList::argList << endl; Info<< "allowSystemOperations : "; - if (codeStreamTools::allowSystemOperations) + if (dynamicCode::allowSystemOperations) { Info<< "Allowing user-supplied system call operations" << endl; } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C index 8b19852db8..a467943f65 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.C @@ -33,8 +33,8 @@ License #include "IFstream.H" #include "OFstream.H" #include "SHA1Digest.H" -#include "OSHA1stream.H" -#include "codeStreamTools.H" +#include "dynamicCode.H" +#include "dynamicCodeContext.H" #include "codeProperties.H" #include "stringOps.H" @@ -78,113 +78,52 @@ Foam::codedFixedValueFvPatchScalarField::dict() const } -void Foam::codedFixedValueFvPatchScalarField::writeLibrary +void Foam::codedFixedValueFvPatchScalarField::createLibrary ( - const fileName& codePath, - const fileName& libPath, - const dictionary& dict + dynamicCode& dynCode, + const dynamicCodeContext& context ) { // Write files for new library - if (!Pstream::master()) + if (Pstream::master() && !dynCode.upToDate(context)) { - return; - } + Info<< "Creating new library in " << dynCode.libPath() << endl; + dynCode.clear(); - // "codeInclude" is optional - string codeInclude; - if (dict.found("codeInclude")) - { - codeInclude = stringOps::trim(dict["codeInclude"]); - stringOps::inplaceExpand(codeInclude, dict); - } + // filter with this context + dynCode.setFilterContext(context); - // "codeOptions" is optional - string codeOptions; - if (dict.found("codeOptions")) - { - codeOptions = stringOps::trim(dict["codeOptions"]); - stringOps::inplaceExpand(codeOptions, dict); - } + // filter C/H template + dynCode.addFilterFile(codeTemplateC); + dynCode.addFilterFile(codeTemplateH); - // "code" is mandatory - string code = stringOps::trim(dict["code"]); - stringOps::inplaceExpand(code, dict); - - - // Create SHA1 digest from the contents - SHA1Digest sha; - { - OSHA1stream os; - os << codeInclude << codeOptions << code; - sha = os.digest(); - } - -// Info<<"old SHA1: " << sha1_ << nl -// <<"new SHA1: " << sha << endl; - - - // only use side-effect of writing SHA1Digest for now - (void) codeStreamTools::upToDate(codePath, sha); - - // TODO: compile on-demand - if (true) - { - Info<< "Creating new library in " << libPath << endl; - - const fileName fileCsrc(codeStreamTools::findTemplate(codeTemplateC)); - const fileName fileHsrc(codeStreamTools::findTemplate(codeTemplateH)); - - // not found! - if (fileCsrc.empty() || fileHsrc.empty()) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchScalarField::writeLibrary(..)", - dict - ) << "Could not find one or both code templates: " - << codeTemplateC << ", " << codeTemplateH << nl - << codeStreamTools::searchedLocations() - << exit(FatalIOError); - } - - - - List copyFiles(2); - copyFiles[0].file() = fileCsrc; - copyFiles[0].set("codeInclude", codeInclude); - copyFiles[0].set("code", code); - copyFiles[0].set("SHA1sum", sha.str()); - - copyFiles[1].file() = fileHsrc; - - - List filesContents(2); - - // Write Make/files - filesContents[0].first() = "Make/files"; - filesContents[0].second() = + // Make/files + dynCode.addCreateFile + ( + "Make/files", codeTemplateC + "\n\n" - + codeStreamTools::libTarget(redirectType_); + + dynCode.libTarget() + ); - // Write Make/options - filesContents[1].first() = "Make/options"; - filesContents[1].second() = + // Make/options + dynCode.addCreateFile + ( + "Make/options", "EXE_INC = -g \\\n" "-I$(LIB_SRC)/finiteVolume/lnInclude\\\n" - + codeOptions - + "\n\nLIB_LIBS = "; + + context.options() + + "\n\nLIB_LIBS = " + ); - codeStreamTools writer(redirectType_, copyFiles, filesContents); - if (!writer.copyFilesContents(codePath)) + if (!dynCode.copyFilesContents()) { FatalIOErrorIn ( "codedFixedValueFvPatchScalarField::writeLibrary(..)", - dict + context.dict() ) << "Failed writing " << nl - << copyFiles << nl - << filesContents + // << copyFiles << nl + // << filesContents << exit(FatalIOError); } } @@ -193,98 +132,113 @@ void Foam::codedFixedValueFvPatchScalarField::writeLibrary void Foam::codedFixedValueFvPatchScalarField::updateLibrary() { - codeStreamTools::checkSecurity + dynamicCode::checkSecurity ( "codedFixedValueFvPatchScalarField::updateLibrary()", dict_ ); - // write code into redirectType_ subdir - const fileName codePath = codeStreamTools::codePath(redirectType_); + // use in-line or via codeProperties + const bool useInlineDict = dict_.found("code"); -// const fileName oldLibPath = codeStreamTools::libPath -// ( -// redirectType_ + "_" + sha1_ -// ); - - // write library into platforms/$WM_OPTIONS/lib subdir - const fileName libPath = codeStreamTools::libPath(redirectType_); + // determine code context (code, codeInclude, codeOptions) + dynamicCodeContext context + ( + useInlineDict + ? dict_ + : this->dict().subDict(redirectType_) + ); - //Info<< "codePath:" << codePath << nl - // << "libPath:" << libPath << endl; + // NOTE: probably don't need codeProperties anymore + // since we use the sha1 directly + if (!useInlineDict) + { + this->dict().setUnmodified(); + } + + // write code into redirectType_ subdir as well + dynamicCode dynCode(redirectType_); + + // The version function name - based on the SHA1 + const string checkFuncName + ( + dynCode.codeName() + "_" + context.sha1().str() + ); + + + const fileName libPath = dynCode.libPath(); void* lib = dlLibraryTable::findLibrary(libPath); - - // TODO: - // calculate old/new SHA1 for code - // check if the correct library version was already loaded. - // Find the library handle. - // - // string signatureName(redirectType_ + "_" + sha().str()); - // void (*signatureFunction)(); - // signatureFunction = reinterpret_cast(dlSym(lib, signatureName)); - - if (dict_.found("code")) + // Load library if not already loaded + bool reusing = false; + if (!lib && dlLibraryTable::open(libPath, false)) { - if (!lib) - { - writeLibrary(codePath, libPath, dict_); - } + lib = dlLibraryTable::findLibrary(libPath); + reusing = true; } - else + + + // library may have loaded, the version may not be correct + bool waiting = false; + if (lib) { - const codeProperties& onTheFlyDict = dict(); - - if (onTheFlyDict.modified()) + // Unload library if needed + if (!dlSym(lib, checkFuncName)) { - onTheFlyDict.setUnmodified(); - - // Remove instantiation of fvPatchField provided by library - redirectPatchFieldPtr_.clear(); - // Unload library - if (lib) + reusing = false; + waiting = true; + if (!dlLibraryTable::close(libPath, false)) { - if (!dlLibraryTable::close(libPath)) - { - FatalIOErrorIn - ( - "codedFixedValueFvPatchScalarField::updateLibrary(..)", - onTheFlyDict - ) << "Failed unloading library " << libPath - << exit(FatalIOError); - } - lib = NULL; + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::updateLibrary(..)", + context.dict() + ) << "Failed unloading library " + << libPath + << exit(FatalIOError); } - - const dictionary& codeDict = onTheFlyDict.subDict(redirectType_); - writeLibrary(codePath, libPath, codeDict); + lib = 0; } + + // unload from all processes + reduce(waiting, orOp()); } + + // create library if (!lib) { + if (useInlineDict) + { + createLibrary(dynCode, context); + } + else + { + // Remove instantiation of fvPatchField provided by library + redirectPatchFieldPtr_.clear(); + createLibrary(dynCode, context); + } + if (Pstream::master()) { - const Foam::string wmakeCmd("wmake libso " + codePath); - Info<< "Invoking " << wmakeCmd << endl; - if (Foam::system(wmakeCmd)) + if (!dynCode.wmakeLibso()) { FatalIOErrorIn ( "codedFixedValueFvPatchScalarField::updateLibrary()", dict_ - ) << "Failed " << wmakeCmd + ) << "Failed wmake " << libPath << exit(FatalIOError); } } // all processes must wait for compile - bool dummy = true; - reduce(dummy, orOp()); + waiting = true; + reduce(waiting, orOp()); - if (!dlLibraryTable::open(libPath)) + if (!dlLibraryTable::open(libPath, false)) { FatalIOErrorIn ( @@ -293,6 +247,29 @@ void Foam::codedFixedValueFvPatchScalarField::updateLibrary() ) << "Failed loading library " << libPath << exit(FatalIOError); } + + + // paranoid - check that signature function is really there + lib = dlLibraryTable::findLibrary(libPath); + if (lib) + { + if (!dlSym(lib, checkFuncName)) + { + FatalIOErrorIn + ( + "codedFixedValueFvPatchScalarField::updateLibrary(..)", + dict_ + ) << "Library loaded - but wrong version!" + << libPath + << exit(FatalIOError); + } + lib = 0; + } + } + else if (reusing) + { + Info<< "Reusing library in " << libPath << nl + << " with " << context.sha1().str() << nl; } } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H index d08059be3a..00bdf64ff0 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchScalarField.H @@ -29,8 +29,6 @@ Description Constructs on-the-fly a new boundary condition (derived from fixedValueFvPatchScalarField) which is then used to evaluate. - See also codeStream. - Example: \verbatim movingWall @@ -71,7 +69,7 @@ Description \endverbatim SeeAlso - Foam::codeStreamTools for constant paths used + Foam::dynamicCode and Foam::functionEntries::codeStream SourceFiles codedFixedValueFvPatchScalarField.C @@ -82,14 +80,16 @@ SourceFiles #define codedFixedValueFvPatchScalarField_H #include "fixedValueFvPatchFields.H" -#include "SHA1Digest.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +// Forward declaration of classes class codeProperties; +class dynamicCode; +class dynamicCodeContext; /*---------------------------------------------------------------------------*\ Class codedFixedValueFvPatchScalarField Declaration @@ -104,10 +104,6 @@ class codedFixedValueFvPatchScalarField //- Dictionary contents for the boundary condition mutable dictionary dict_; - //- SHA1Digest of the Dictionary contents - // Currently unused, but useful for reloading? - mutable SHA1Digest sha1_; - const word redirectType_; mutable autoPtr redirectPatchFieldPtr_; @@ -117,12 +113,7 @@ class codedFixedValueFvPatchScalarField const codeProperties& dict() const; - void writeLibrary - ( - const fileName& dir, - const fileName& libPath, - const dictionary& dict - ); + void createLibrary(dynamicCode&, const dynamicCodeContext& dict); void updateLibrary(); diff --git a/src/postProcessing/functionObjects/systemCall/systemCall.C b/src/postProcessing/functionObjects/systemCall/systemCall.C index 0a9d825644..90c34dd286 100644 --- a/src/postProcessing/functionObjects/systemCall/systemCall.C +++ b/src/postProcessing/functionObjects/systemCall/systemCall.C @@ -25,7 +25,7 @@ License #include "systemCall.H" #include "Time.H" -#include "codeStreamTools.H" +#include "dynamicCode.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -71,7 +71,7 @@ void Foam::systemCall::read(const dictionary& dict) << "no executeCalls, endCalls or writeCalls defined." << endl; } - else if (!codeStreamTools::allowSystemOperations) + else if (!dynamicCode::allowSystemOperations) { FatalErrorIn (