void mitk::BaseData::UnRegister() const { #ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED if(GetReferenceCount()>1) { Superclass::UnRegister(); if((m_Unregistering==false) && (m_SmartSourcePointer.IsNotNull())) { m_Unregistering=true; // the order of the following boolean statement is important: // this->GetSource() returns a SmartPointer, // which increases and afterwards decreases the reference count, // which may result in an ExternalReferenceCount of 0, causing // BaseProcess::UnRegister() to destroy us (also we already // about to do that). if((this->m_SmartSourcePointer->GetExternalReferenceCount()==0) || (this->GetSource().IsNull())) m_SmartSourcePointer=NULL; // now the reference count is zero and this object has been destroyed; thus nothing may be done after this line!! else m_Unregistering=false; } } else #endif Superclass::UnRegister(); // now the reference count is zero and this object has been destroyed; thus nothing may be done after this line!! }
void mitk::BaseProcess::UnRegister() const { #ifdef MITK_WEAKPOINTER_PROBLEM_WORKAROUND_ENABLED if((m_Unregistering==false) && (m_CalculatingExternalReferenceCount==false)) { m_Unregistering=true; int realReferenceCount = GetExternalReferenceCount()-1; //-1 because someone is trying to unregister us if(realReferenceCount<0) m_ExternalReferenceCount=realReferenceCount=0; if(realReferenceCount==0) { DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs(); //disconnect all outputs from us //size of outputs will not change until the very last output //is removed, because we remove from front to back unsigned int idx; for (idx = 0; idx < outputs.size(); ++idx) { const_cast<mitk::BaseProcess*>(this)->RemoveOutput(outputs[idx]); } //now the referenceCount should be one! int testReferenceCount=GetReferenceCount(); if(testReferenceCount!=1) { itkWarningMacro(<<"Reference count of process object unexpectedly " << "not 1 before final unregister but " << testReferenceCount); }
int mitk::BaseData::GetExternalReferenceCount() const { if(m_CalculatingExternalReferenceCount==false) //this is only needed because a smart-pointer to m_Outputs (private!!) must be created by calling GetOutputs. { m_CalculatingExternalReferenceCount = true; m_ExternalReferenceCount = -1; int realReferenceCount = GetReferenceCount(); if(GetSource().IsNull()) { m_ExternalReferenceCount = realReferenceCount; m_CalculatingExternalReferenceCount = false; return m_ExternalReferenceCount; } mitk::BaseProcess::DataObjectPointerArray outputs = m_SmartSourcePointer->GetOutputs(); unsigned int idx; for (idx = 0; idx < outputs.size(); ++idx) { //references of outputs that are not referenced from someone else (reference additional to the reference from this BaseProcess object) are interpreted as non-existent if(outputs[idx]==this) --realReferenceCount; } m_ExternalReferenceCount = realReferenceCount; if(m_ExternalReferenceCount<0) m_ExternalReferenceCount=0; m_CalculatingExternalReferenceCount = false; } else return -1; return m_ExternalReferenceCount; }
int mitk::BaseProcess::GetExternalReferenceCount() const { if(m_CalculatingExternalReferenceCount==false) //this is only needed because a smart-pointer to m_Outputs (private!!) must be created by calling GetOutputs. { m_CalculatingExternalReferenceCount = true; m_ExternalReferenceCount = -1; DataObjectPointerArray& outputs = const_cast<mitk::BaseProcess*>(this)->GetOutputs(); int realReferenceCount = GetReferenceCount(); unsigned int idx; for (idx = 0; idx < outputs.size(); ++idx) { //references of outputs that are not referenced from someone else (reference additional to the reference from this BaseProcess object) are interpreted as non-existent if((outputs[idx]) && (outputs[idx]->GetReferenceCount()==1)) --realReferenceCount; } m_ExternalReferenceCount = realReferenceCount; if(m_ExternalReferenceCount<0) m_ExternalReferenceCount=0; } else return -1; m_CalculatingExternalReferenceCount = false; //do not move in if-part!!! return m_ExternalReferenceCount; }