Commit e120df09 authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

ENH: improved handling of regIOobject deletion (#1276)

- remove registration and ownership before deleting a regIOobject
  from within objectRegistry to avoid possible recursion.

- regIOobject destructor now removes any registered object from
  registry regardless if ownedByRegistry or not. It also removes
  always removes the ownership flag to avoid possible recursion.

- the regIOobject::checkOut() now unconditionally clears file watches.
  These will only be there if the object is registered (a no-op for an
  unregistered object), but this additional safety is needed to manage
  case where the registration has been modified elsewhere (eg, by the
  objectRegistry).
parent 073e0a7f
......@@ -333,14 +333,9 @@ bool Foam::objectRegistry::checkOut(const word& key) const
void Foam::objectRegistry::clear()
{
// Free anything owned by the registry
// This needs to be done in two stages:
// - collect objects-to-be-removed
// - 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;
// Free anything owned by the registry, but first unset both
// 'ownedByRegistry' and 'registered' flags to ensure that the
// regIOobject destructor will not affect the registry
for (iterator iter = begin(); iter != end(); ++iter)
{
......@@ -348,26 +343,16 @@ void Foam::objectRegistry::clear()
if (ptr && ptr->ownedByRegistry())
{
// TBD: may wish to have ptr->clearWatches();
if (objectRegistry::debug)
{
Pout<< "objectRegistry::clear : " << ptr->name()
<< " watches :" << flatOutput(ptr->watchIndices()) << nl;
Pout<< "objectRegistry::clear : " << ptr->name() << 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();
}
......@@ -381,18 +366,18 @@ void Foam::objectRegistry::clearStorage()
bool Foam::objectRegistry::erase(const iterator& iter)
{
// Free anything owned by the registry
// Remove from registry - see notes in objectRegistry::clear()
if (iter.found())
{
regIOobject* ptr = iter.val();
bool ok = HashTable<regIOobject*>::erase(iter);
const bool ok = HashTable<regIOobject*>::erase(iter);
if (ptr && ptr->ownedByRegistry())
{
// TBD: may wish to have ptr->clearWatches();
delete ptr;
ptr->release(true); // Relinquish ownership and registration
delete ptr; // Delete also clears fileHandler watches
}
return ok;
......
......@@ -156,19 +156,36 @@ Foam::regIOobject::~regIOobject()
{
if (objectRegistry::debug)
{
Pout<< "Destroying regIOobject called " << name()
<< " of type " << type()
<< " registered " << registered_
<< " owned " << ownedByRegistry_
<< " in directory " << path()
Pout<< "Destroy regIOobject: " << name()
<< " type=" << type()
<< " registered=" << registered_
<< " owned=" << ownedByRegistry_
<< " directory=" << path()
<< endl;
}
// Check out of objectRegistry if not owned by the registry
if (!ownedByRegistry_)
{
checkOut();
}
// Deletion of a regIOobject should remove itself from its registry
// (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();
}
......@@ -212,15 +229,16 @@ bool Foam::regIOobject::checkIn()
bool Foam::regIOobject::checkOut()
{
forAllReverse(watchIndices_, i)
{
fileHandler().removeWatch(watchIndices_[i]);
}
watchIndices_.clear();
if (registered_)
{
registered_ = false;
forAllReverse(watchIndices_, i)
{
fileHandler().removeWatch(watchIndices_[i]);
}
watchIndices_.clear();
return db().checkOut(*this);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment