diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.C b/src/OpenFOAM/db/objectRegistry/objectRegistry.C index fc3c4c8651fc8f49196b63a4f6090b30110e7f64..fe9cdb2a9e4a2ce36cd0ce041126d2158daafe30 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistry.C +++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.C @@ -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; diff --git a/src/OpenFOAM/db/regIOobject/regIOobject.C b/src/OpenFOAM/db/regIOobject/regIOobject.C index a933fd799d8c2d5130b420af37d3ab032ac8fbbd..b9abc11951b3378353a9464ea5638ffaeb4ad972 100644 --- a/src/OpenFOAM/db/regIOobject/regIOobject.C +++ b/src/OpenFOAM/db/regIOobject/regIOobject.C @@ -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); }