Merge branch 'fix-GL1276' into 'develop'

ENH: improved handling of regIOobject deletion (#1276)

See merge request Development/OpenFOAM-plus!263
This commit is contained in:
Andrew Heather
2019-06-04 14:32:30 +01:00
committed by Andrew Heather
2 changed files with 43 additions and 40 deletions

View File

@ -333,14 +333,9 @@ bool Foam::objectRegistry::checkOut(const word& key) const
void Foam::objectRegistry::clear() void Foam::objectRegistry::clear()
{ {
// Free anything owned by the registry // Free anything owned by the registry, but first unset both
// This needs to be done in two stages: // 'ownedByRegistry' and 'registered' flags to ensure that the
// - collect objects-to-be-removed // regIOobject destructor will not affect the registry
// - actually delete objects
// since the destructor of the regIOobject will actually delete its
// entry from the objectRegistry which messes up the iterator.
DynamicList<regIOobject*> owned;
for (iterator iter = begin(); iter != end(); ++iter) for (iterator iter = begin(); iter != end(); ++iter)
{ {
@ -348,26 +343,16 @@ void Foam::objectRegistry::clear()
if (ptr && ptr->ownedByRegistry()) if (ptr && ptr->ownedByRegistry())
{ {
// TBD: may wish to have ptr->clearWatches();
if (objectRegistry::debug) if (objectRegistry::debug)
{ {
Pout<< "objectRegistry::clear : " << ptr->name() Pout<< "objectRegistry::clear : " << ptr->name() << nl;
<< " watches :" << flatOutput(ptr->watchIndices()) << nl;
} }
owned.append(ptr); ptr->release(true); // Relinquish ownership and registration
delete ptr; // Delete also clears fileHandler watches
} }
} }
for (regIOobject* objectPtr : owned)
{
// Make sure that the destructor of the regIOobject does a checkout
objectPtr->release();
delete objectPtr;
}
HashTable<regIOobject*>::clear(); HashTable<regIOobject*>::clear();
} }
@ -381,18 +366,18 @@ void Foam::objectRegistry::clearStorage()
bool Foam::objectRegistry::erase(const iterator& iter) bool Foam::objectRegistry::erase(const iterator& iter)
{ {
// Free anything owned by the registry // Remove from registry - see notes in objectRegistry::clear()
if (iter.found()) if (iter.found())
{ {
regIOobject* ptr = iter.val(); regIOobject* ptr = iter.val();
bool ok = HashTable<regIOobject*>::erase(iter); const bool ok = HashTable<regIOobject*>::erase(iter);
if (ptr && ptr->ownedByRegistry()) if (ptr && ptr->ownedByRegistry())
{ {
// TBD: may wish to have ptr->clearWatches(); ptr->release(true); // Relinquish ownership and registration
delete ptr; delete ptr; // Delete also clears fileHandler watches
} }
return ok; return ok;

View File

@ -156,19 +156,36 @@ Foam::regIOobject::~regIOobject()
{ {
if (objectRegistry::debug) if (objectRegistry::debug)
{ {
Pout<< "Destroying regIOobject called " << name() Pout<< "Destroy regIOobject: " << name()
<< " of type " << type() << " type=" << type()
<< " registered " << registered_ << " registered=" << registered_
<< " owned " << ownedByRegistry_ << " owned=" << ownedByRegistry_
<< " in directory " << path() << " directory=" << path()
<< endl; << endl;
} }
// Check out of objectRegistry if not owned by the registry // Deletion of a regIOobject should remove itself from its registry
if (!ownedByRegistry_) // (ie, checkOut), but there are different paths for destruction to occur.
{ // The complications are only when the object is ownedByRegistry.
//
// 1. The objectRegistry clear()/erase() is called (and object is
// 'ownedByRegistry').
//
// - Mark as unowned/unregistered prior to deletion.
// This ensures that this checkOut() only clears file watches and
// does nothing else.
//
// 2. The regIOobject is deleted directly (and also 'ownedByRegistry').
//
// - Mark as unowned (but keep as registered) prior to triggering
// checkOut(). By being 'unowned', the registry will not attempt a
// second deletion when the object name is removed from the registry.
// Revoke any registry ownership: we are already deleting
ownedByRegistry_ = false;
// Remove registered object from objectRegistry
checkOut(); checkOut();
}
} }
@ -212,15 +229,16 @@ bool Foam::regIOobject::checkIn()
bool Foam::regIOobject::checkOut() bool Foam::regIOobject::checkOut()
{ {
if (registered_)
{
registered_ = false;
forAllReverse(watchIndices_, i) forAllReverse(watchIndices_, i)
{ {
fileHandler().removeWatch(watchIndices_[i]); fileHandler().removeWatch(watchIndices_[i]);
} }
watchIndices_.clear(); watchIndices_.clear();
if (registered_)
{
registered_ = false;
return db().checkOut(*this); return db().checkOut(*this);
} }