Hi Nil,
I just entered bug
http://bugs.mitk.org/show_bug.cgi?id=18672
for this. Could you please try the attached patch for me (based on
2014.10), without any other proposed fixes from this mail thread?
Thanks,
Sascha
On 01/12/2015 08:18 PM, Nil Goyette wrote:
Hi all,
I have at least two nodes (I have drawn more, but I can reproduce the
bug with 2 nodes)
- Node1
--- Node2 (child of Node1)
--- Node3
----- Node4
----- Node5
- Some other nodes
When the user deletes Node1, I want to delete all children nodes (2,
3, 4, 5).
To do so, I use NodeDeleted(), I ask the DataStorage for all
derivative nodes of the deleted node and delete them all.
A problem arises when the user highlights all nodes and delete them.
Some nodes are deleted more then one time. Of course, there are
conditions in mitk and in my own code that check if the node is null,
but it still fails about half of the time. Since the NodeRemoved()
event is thrown *before* the actual deletion, the null/exists checks
are useless.
I'm probably not the first that want to delete all the children of a
node. I feel that this should be simple. Is there a feature to do it
that I'm not aware of?
--
Logo Imeka <http://imeka.ca/> Nil Goyette, M.Sc.
www.imeka.ca <http://imeka.ca/>
diff --git a/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp b/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp
index 207cfbb..12d124e 100644
--- a/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp
+++ b/Core/Code/DataManagement/mitkStandaloneDataStorage.cpp
@@ -24,6 +24,26 @@ See LICENSE.txt or http://www.mitk.org for details.
#include "itkSimpleFastMutexLock.h"
#include "itkMutexLockHolder.h"
+class DoubleDeletionGuard
+{
+public:
+ DoubleDeletionGuard(const itk::Object* obj)
+ : m_Obj(const_cast<itk::Object*>(obj))
+ , m_ObjDeleted(obj == NULL ? false : obj->GetReferenceCount() == 0)
+ {
+ if (m_ObjDeleted) m_Obj->SetReferenceCount(1);
+ }
+
+ ~DoubleDeletionGuard()
+ {
+ if (m_ObjDeleted) m_Obj->SetReferenceCount(0);
+ }
+
+private:
+ itk::Object* m_Obj;
+ bool m_ObjDeleted;
+};
+
mitk::StandaloneDataStorage::StandaloneDataStorage()
: mitk::DataStorage()
@@ -128,11 +148,16 @@ void mitk::StandaloneDataStorage::Remove(const mitk::DataNode* node)
bool mitk::StandaloneDataStorage::Exists(const mitk::DataNode* node) const
{
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_Mutex);
- return (m_SourceNodes.find(node) != m_SourceNodes.end());
+ // avoid possible double deletion
+ DoubleDeletionGuard guard(node);
+ return m_SourceNodes.find(node) != m_SourceNodes.end();
}
void mitk::StandaloneDataStorage::RemoveFromRelation(const mitk::DataNode* node, AdjacencyList& relation)
{
+ // avoid possible double deletion
+ DoubleDeletionGuard guard(node);
+
for (AdjacencyList::const_iterator mapIter = relation.begin(); mapIter != relation.end(); ++mapIter) // for each node in the relation
if (mapIter->second.IsNotNull()) // if node has a relation list
{
@@ -173,6 +198,9 @@ mitk::DataStorage::SetOfObjects::ConstPointer mitk::StandaloneDataStorage::GetRe
if (node == NULL)
throw std::invalid_argument("invalid node");
+ // avoid possible double deletion
+ DoubleDeletionGuard guard(node);
+
/* Either read direct relations directly from adjacency list */
if (onlyDirectlyRelated)
{
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
mitk-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mitk-users