From b0072bfab8666b3b1a8fee4ae951b4581183ee5e Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 9 Jan 2020 12:27:45 +0100 Subject: [PATCH] ENH: regIOobject store() now also registers the object - previously the store() method just set the ownedByRegistry flag. Now ensure that it is indeed registered first. - support register/store of tmp<> items. The tmp parameter is not cleared, but changed from PTR to CREF to allow further use. The implicit registration allows code simplification using the GeometricField::New factory method, for example. Old Code ======== volScalarField* ptr = new volScalarField ( IOobject ( fieldName, mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE, true // Register ), mesh, dimless, zeroGradientFvPatchField::typeName ); ptr->store(); New Code ======== auto tptr = volScalarField::New ( fieldName, mesh, dimless, zeroGradientFvPatchField::typeName ); regIOobject::store(tptr); or even regIOobject::store ( volScalarField::New ( fieldName, mesh, dimless, zeroGradientFvPatchField::typeName ) ); --- src/OpenFOAM/db/regIOobject/regIOobject.C | 4 + src/OpenFOAM/db/regIOobject/regIOobject.H | 57 +++++++++++---- src/OpenFOAM/db/regIOobject/regIOobjectI.H | 73 +++++++++++++++++-- .../angledDuct/implicit/system/sampling | 17 ++--- 4 files changed, 117 insertions(+), 34 deletions(-) diff --git a/src/OpenFOAM/db/regIOobject/regIOobject.C b/src/OpenFOAM/db/regIOobject/regIOobject.C index eb938a6605..d1dd2e90d3 100644 --- a/src/OpenFOAM/db/regIOobject/regIOobject.C +++ b/src/OpenFOAM/db/regIOobject/regIOobject.C @@ -109,6 +109,7 @@ Foam::regIOobject::regIOobject(const regIOobject& rio, bool registerCopy) { if (rio.registered_) { + // Unregister the original object const_cast(rio).checkOut(); } checkIn(); @@ -132,6 +133,9 @@ Foam::regIOobject::regIOobject { if (registerCopy) { + // NOTE: could also unregister the original object + // if (rio.registered_ && newName == rio.name()) ... + checkIn(); } } diff --git a/src/OpenFOAM/db/regIOobject/regIOobject.H b/src/OpenFOAM/db/regIOobject/regIOobject.H index e990fa7ab6..6793e7000b 100644 --- a/src/OpenFOAM/db/regIOobject/regIOobject.H +++ b/src/OpenFOAM/db/regIOobject/regIOobject.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2018-2019 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -88,7 +88,7 @@ protected: private: - // Private data + // Private Data //- Is this object registered with the registry bool registered_; @@ -117,8 +117,8 @@ private: public: - //- Declare friendship with any classes that need access to - // masterOnlyReading + //- Declare friendship with classes that need access to + //- masterOnlyReading friend class functionEntries::codeStream; friend class fileOperations::uncollatedFileOperation; friend class fileOperations::masterUncollatedFileOperation; @@ -164,7 +164,8 @@ public: // Registration //- Add object to registry, if not already registered - // \return true if object was newly registered + // \return true if object was already registered, + // or was newly registered bool checkIn(); //- Remove all file watches and remove object from registry @@ -177,30 +178,53 @@ public: //- Is this object owned by the registry? inline bool ownedByRegistry() const; - //- Transfer ownership of this object to its registry - inline void store(); + //- Register object with its registry + //- and transfer ownership to the registry. + // \return true if now ownedByRegistry + inline bool store(); - //- Transfer ownership of the given object pointer to its registry + //- Register object pointer with its registry + //- and transfer ownership to the registry. // \return reference to the object. template inline static Type& store(Type* p); - //- Transfer ownership of the given object pointer to its registry + //- Register object pointer with its registry + //- and transfer ownership to the registry. + // Clears the autoPtr parameter. // \return reference to the object. template inline static Type& store(autoPtr& aptr); - //- Transfer ownership of the given object pointer to its registry + //- Register object pointer with its registry + //- and transfer ownership to the registry. + // Clears the autoPtr parameter. // \return reference to the object. template inline static Type& store(autoPtr&& aptr); + //- Register temporary pointer with its registry + //- and transfer ownership of pointer to the registry. + // After the call, tmp parameter changes from PTR to CREF. + // + // \return reference to the object. + template + inline static Type& store(tmp& tptr); + + //- Register temporary pointer with its registry + //- and transfer ownership of pointer to the registry. + // After the call, the tmp parameter content is \em unspecified. + // + // \return reference to the object. + template + inline static Type& store(tmp&& tptr); + //- Release ownership of this object from its registry // \param unregister optionally set as non-registered inline void release(const bool unregister = false); - // Dependency checking + // Dependency Checking //- Event number at last update. inline label eventNo() const; @@ -271,8 +295,8 @@ public: //- Read object virtual bool read(); - //- Add file watch for fileName on object if not yet watched. Return - // index of watch + //- Add file watch for fileName on object if not yet watched. + // \return index of watch virtual label addWatch(const fileName&); //- Return file-monitoring handles @@ -282,7 +306,7 @@ public: inline labelList& watchIndices(); //- Return true if the object's file (or files for objectRegistry) - // have been modified. (modified state is cached by Time) + //- have been modified. (modified state is cached by Time) virtual bool modified() const; //- Read object if modified (as set by call to modified) @@ -317,9 +341,10 @@ public: } - // Member operators + // Member Operators - void operator=(const IOobject&); + //- Copy assignment + void operator=(const IOobject& io); }; diff --git a/src/OpenFOAM/db/regIOobject/regIOobjectI.H b/src/OpenFOAM/db/regIOobject/regIOobjectI.H index 51f953425a..07623d9368 100644 --- a/src/OpenFOAM/db/regIOobject/regIOobjectI.H +++ b/src/OpenFOAM/db/regIOobject/regIOobjectI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2018-2019 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -34,9 +34,19 @@ inline bool Foam::regIOobject::ownedByRegistry() const } -inline void Foam::regIOobject::store() +inline bool Foam::regIOobject::store() { - ownedByRegistry_ = true; + if (checkIn()) + { + ownedByRegistry_ = true; + } + else + { + WarningInFunction + << "Refuse to store unregistered object: " << this->name() << nl; + } + + return ownedByRegistry_; } @@ -50,7 +60,15 @@ inline Type& Foam::regIOobject::store(Type* p) << abort(FatalError); } - p->regIOobject::ownedByRegistry_ = true; + const bool ok = p->regIOobject::store(); + + if (!ok) + { + FatalErrorInFunction + << "Failed to store pointer: " << p->regIOobject::name() + << ". Risk of memory leakage\n" + << abort(FatalError); + } return *p; } @@ -59,14 +77,57 @@ inline Type& Foam::regIOobject::store(Type* p) template inline Type& Foam::regIOobject::store(autoPtr& aptr) { - return store(aptr.ptr()); // release, pass management to regIOobject + // Pass management to objectRegistry + return store(aptr.release()); } template inline Type& Foam::regIOobject::store(autoPtr&& aptr) { - return store(aptr.ptr()); // release, pass management to regIOobject + // Pass management to objectRegistry + return store(aptr.release()); +} + + +template +inline Type& Foam::regIOobject::store(tmp& tptr) +{ + Type* p = nullptr; + + if (tptr.isTmp()) + { + // Pass management to objectRegistry + p = tptr.ptr(); + + store(p); + + // Adjust tmp<> access to use the stored reference + tptr.cref(*p); + } + else + { + // Taking ownership of a const-ref does not make much sense. + // - Storing the object won't actually do so, it will be removed + // when the original object goes out of scope. + // - Storing a clone may not be what we want. + + p = tptr.get(); + + WarningInFunction + << "Refuse to store tmp to const-ref: " << p->name() + << ". Likely indicates a coding error\n"; + } + + return *p; +} + + +template +inline Type& Foam::regIOobject::store(tmp&& tptr) +{ + // Treat like a normal reference + return store(tptr); } diff --git a/tutorials/compressible/rhoPorousSimpleFoam/angledDuct/implicit/system/sampling b/tutorials/compressible/rhoPorousSimpleFoam/angledDuct/implicit/system/sampling index 5473d3ab85..97787368e7 100644 --- a/tutorials/compressible/rhoPorousSimpleFoam/angledDuct/implicit/system/sampling +++ b/tutorials/compressible/rhoPorousSimpleFoam/angledDuct/implicit/system/sampling @@ -34,24 +34,17 @@ cellZoneID { if (!volZonePtr) { - volZonePtr = new volScalarField + volZonePtr = ®IOobject::store ( - IOobject + volScalarField::New ( fieldName, - mesh.time().timeName(), mesh, - IOobject::NO_READ, - IOobject::NO_WRITE, - true // Register - ), - mesh, - dimless, - zeroGradientFvPatchField::typeName + dimless, + zeroGradientFvPatchField::typeName + ) ); - volZonePtr->store(); - Info<< "Creating " << fieldName << " field for postProcessing" << nl; }