Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

203 lines
7.9 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkGarbageCollector.h,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkGarbageCollector - Detect and break reference loops
// .SECTION Description
// vtkGarbageCollector is used by VTK classes that may be involved in
// reference counting loops (such as Algorithm <-> Executive). It
// detects strongly connected components of the reference graph that
// have been leaked deletes them. The garbage collector uses the
// ReportReferences method to search the reference graph and construct
// a net reference count for each connected component. If the net
// reference count is zero the entire set of objects is deleted.
// Deleting each component may leak other components, which are then
// collected recursively.
//
// To enable garbage collection for a class, add these members:
//
// \code
//
// public:
// virtual void Register(vtkObjectBase* o)
// {
// this->RegisterInternal(o, 1);
// }
// virtual void UnRegister(vtkObjectBase* o)
// {
// this->UnRegisterInternal(o, 1);
// }
//
// protected:
//
// virtual void ReportReferences(vtkGarbageCollector* collector)
// {
// // Report references held by this object that may be in a loop.
// this->Superclass::ReportReferences(collector);
// vtkGarbageCollectorReport(collector, this->OtherObject, "Other Object");
// }
// \endcode
//
// The implementations should be in the .cxx file in practice.
// It is important that the reference be reported using the real
// pointer or smart pointer instance that holds the reference. When
// collecting the garbage collector will actually set this pointer to
// NULL. The destructor of the class should be written to deal with
// this. It is also expected that an invariant is maintained for any
// reference that is reported. The variable holding the reference
// must always either be NULL or refer to a fully constructed valid
// object. Therefore code like "this->Object->UnRegister(this)" must
// be avoided if "this->Object" is a reported reference because it
// is possible that the object is deleted before UnRegister returns
// but then "this->Object" will be left as a dangling pointer. Instead
// use code like
//
// vtkObjectBase* obj = this->Object;
// this->Object = 0;
// obj->UnRegister(this);
//
// so that the reported reference maintains the invariant.
//
// If subclassing from a class that already supports garbage
// collection, one need only provide the ReportReferences method.
#ifndef __vtkGarbageCollector_h
#define __vtkGarbageCollector_h
#include "vtkObject.h"
#include "vtkGarbageCollectorManager.h" // Needed for singleton initialization.
// This function is a friend of the collector so that it can call the
// internal report method.
void VTK_COMMON_EXPORT
vtkGarbageCollectorReportInternal(vtkGarbageCollector*,
vtkObjectBase*, void*,
const char*);
// This allows vtkObjectBase to get at the methods it needs.
class vtkObjectBaseToGarbageCollectorFriendship;
class VTK_COMMON_EXPORT vtkGarbageCollector : public vtkObject
{
public:
vtkTypeRevisionMacro(vtkGarbageCollector,vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
static vtkGarbageCollector* New();
// Description:
// Collect immediately using any objects whose collection was
// previously deferred as a root for the reference graph walk.
// Strongly connected components in the reference graph are
// identified. Those with a net reference count of zero are
// deleted. When a component is deleted it may remove references to
// other components that are not part of the same reference loop but
// are held by objects in the original component. These removed
// references are handled as any other and their corresponding
// checks may be deferred. This method keeps collecting until no
// deferred collection checks remain.
static void Collect();
// Description:
// Collect immediately using the given object as the root for a
// reference graph walk. Strongly connected components in the
// reference graph are identified. Those with a net reference count
// of zero are deleted. When a component is deleted it may remove
// references to other components that are not part of the same
// reference loop but are held by objects in the original component.
// These removed references are handled as any other and their
// corresponding checks may be deferred. This method does continue
// collecting in this case.
static void Collect(vtkObjectBase* root);
// Description:
// Push/Pop whether to do deferred collection. Whenever the total
// number of pushes exceeds the total number of pops collection will
// be deferred. Code can call the Collect method directly to force
// collection.
static void DeferredCollectionPush();
static void DeferredCollectionPop();
// Description:
// Set/Get global garbage collection debugging flag. When set to 1,
// all garbage collection checks will produce debugging information.
static void SetGlobalDebugFlag(int flag);
static int GetGlobalDebugFlag();
protected:
vtkGarbageCollector();
~vtkGarbageCollector();
private:
// Description:
// Called by UnRegister method of an object that supports garbage
// collection. The UnRegister may not actually decrement the
// reference count, but instead hands the reference to the garbage
// collector. If a reference can be given, this method accepts it
// from the caller by returning 1. If the reference cannot be
// accepted then it returns 0. This may be the case when delayed
// garbage collection is disabled, or when the collector has decided
// it is time to do a check.
static int GiveReference(vtkObjectBase* obj);
// Description:
// Called by Register method of an object that supports garbage
// collection. The Register may not actually increment the
// reference count if it can take a reference previously handed to
// the garbage collector. If a reference can be taken, this method
// hands it back to the caller by returning 1. If no reference is
// available, returns 0.
static int TakeReference(vtkObjectBase* obj);
// Singleton management functions.
static void ClassInitialize();
static void ClassFinalize();
//BTX
friend class vtkGarbageCollectorManager;
friend class vtkObjectBaseToGarbageCollectorFriendship;
//ETX
// Internal report callback and friend function that calls it.
virtual void Report(vtkObjectBase* obj, void* ptr, const char* desc);
friend void VTK_COMMON_EXPORT
vtkGarbageCollectorReportInternal(vtkGarbageCollector*,
vtkObjectBase*, void*,
const char*);
private:
vtkGarbageCollector(const vtkGarbageCollector&); // Not implemented.
void operator=(const vtkGarbageCollector&); // Not implemented.
};
//BTX
class vtkSmartPointerBase;
// Description:
// Function to report a reference held by a smart pointer to a collector.
void VTK_COMMON_EXPORT
vtkGarbageCollectorReport(vtkGarbageCollector* collector,
vtkSmartPointerBase& ptr,
const char* desc);
// Description:
// Function to report a reference held by a raw pointer to a collector.
template <class T>
void vtkGarbageCollectorReport(vtkGarbageCollector* collector, T*& ptr,
const char* desc)
{
vtkGarbageCollectorReportInternal(collector, ptr, &ptr, desc);
}
//ETX
#endif