Commit 7ca4b366 authored by Brad King's avatar Brad King 💬
Browse files

BUG: Reverting kmorel's static destruction changes. The current singleton...

BUG: Reverting kmorel's static destruction changes.  The current singleton mangement approach is designed extremely carefully.  Whatever problem caused these changes has another solution.
parent 6d1f7a26
......@@ -149,7 +149,6 @@ public:
ExecuteInformationEvent,
RenderWindowMessageEvent,
WrongTagEvent,
ProgramExitEvent,
UserEvent = 1000
};
//ETX
......
......@@ -15,24 +15,12 @@
#include "vtkDebugLeaks.h"
#include "vtkObjectFactory.h"
#include "vtkCriticalSection.h"
#include "vtkCommand.h"
#include <vtkstd/string>
static const char *vtkDebugLeaksIgnoreClasses[] = {
0
};
//-----------------------------------------------------------------------------
class vtkDebugLeaks::CleanupCommandList
{
public:
CleanupCommandList(vtkCommand *c, CleanupCommandList *n)
: Command(c), Next(n) {}
vtkCommand *Command;
vtkDebugLeaks::CleanupCommandList *Next;
};
//----------------------------------------------------------------------------
// return 1 if the class should be ignored
int vtkDebugLeaksIgnoreClassesCheck(const char* s)
......@@ -49,7 +37,7 @@ int vtkDebugLeaksIgnoreClassesCheck(const char* s)
return 0;
}
vtkCxxRevisionMacro(vtkDebugLeaks, "1.32");
vtkCxxRevisionMacro(vtkDebugLeaks, "1.33");
vtkStandardNewMacro(vtkDebugLeaks);
//----------------------------------------------------------------------------
......@@ -399,16 +387,6 @@ int vtkDebugLeaks::DisplayMessageBox(const char*)
}
#endif
//-----------------------------------------------------------------------------
void vtkDebugLeaks::AddCleanupCommand(vtkCommand *command)
{
if (!command) return;
vtkDebugLeaks::CleanupCommands
= new vtkDebugLeaks::CleanupCommandList(command,
vtkDebugLeaks::CleanupCommands);
vtkDebugLeaks::CleanupCommands->Command->Register(NULL);
}
//----------------------------------------------------------------------------
void vtkDebugLeaks::ClassInitialize()
{
......@@ -422,22 +400,11 @@ void vtkDebugLeaks::ClassInitialize()
vtkDebugLeaks::MemoryTable = 0;
vtkDebugLeaks::CriticalSection = 0;
#endif
vtkDebugLeaks::CleanupCommands = NULL;
}
//----------------------------------------------------------------------------
void vtkDebugLeaks::ClassFinalize()
{
while (vtkDebugLeaks::CleanupCommands)
{
vtkDebugLeaks::CleanupCommandList *l = vtkDebugLeaks::CleanupCommands;
vtkDebugLeaks::CleanupCommands = l->Next;
l->Command->Execute(NULL, vtkCommand::ProgramExitEvent, NULL);
l->Command->Delete();
delete l;
}
#ifdef VTK_DEBUG_LEAKS
if(vtkDebugLeaks::PrintCurrentLeaks() && getenv("VTK_DEBUG_LEAKS_ABORT"))
{
......@@ -462,6 +429,3 @@ vtkDebugLeaksHashTable* vtkDebugLeaks::MemoryTable;
// Purposely not initialized. ClassInitialize will handle it.
vtkSimpleCriticalSection* vtkDebugLeaks::CriticalSection;
// Purposely not initialized. ClassInitialize will handle it.
vtkDebugLeaks::CleanupCommandList* vtkDebugLeaks::CleanupCommands;
......@@ -33,7 +33,6 @@
class vtkDebugLeaksHashTable;
class vtkSimpleCriticalSection;
class vtkCommand;
class VTK_COMMON_EXPORT vtkDebugLeaks : public vtkObject
{
......@@ -54,14 +53,6 @@ public:
// were leaks.
static int PrintCurrentLeaks();
// Description:
// Sometimes a VTK object will be held in a global or static variable.
// This means it may still be around at program exit even though it is
// not really a leak. To prevent debug leaks from reporting it,
// add a vtkCommand that will destroy the particular static variable.
// The command will be called with a vtkCommand::ProgramExitEvent.
static void AddCleanupCommand(vtkCommand *command);
// Description:
// Turn prompt at exit on/off (this setting is deprecated and will
// be ignored).
......@@ -85,11 +76,6 @@ private:
static vtkDebugLeaksHashTable* MemoryTable;
static vtkSimpleCriticalSection* CriticalSection;
//BTX
class CleanupCommandList;
//ETX
static CleanupCommandList *CleanupCommands;
vtkDebugLeaks(const vtkDebugLeaks&); // Not implemented.
void operator=(const vtkDebugLeaks&); // Not implemented.
};
......
......@@ -19,25 +19,17 @@
#endif
#include "vtkObjectFactory.h"
#include "vtkDebugLeaks.h"
#include "vtkCallbackCommand.h"
vtkCxxRevisionMacro(vtkOutputWindow, "1.34");
vtkCxxRevisionMacro(vtkOutputWindow, "1.35");
//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkOutputWindow);
//-----------------------------------------------------------------------------
// Used to cleanup the output window in use on exit.
static void CleanupOutputWindow(vtkObject *, unsigned long, void *, void *)
{
vtkOutputWindow::SetInstance(NULL);
}
//----------------------------------------------------------------------------
vtkOutputWindow* vtkOutputWindow::Instance = 0;
int vtkOutputWindow::CleanupCommandRegistered = 0;
vtkOutputWindowCleanup vtkOutputWindow::Cleanup;
void vtkOutputWindowDisplayText(const char* message)
{
......@@ -64,6 +56,16 @@ void vtkOutputWindowDisplayDebugText(const char* message)
vtkOutputWindow::GetInstance()->DisplayDebugText(message);
}
vtkOutputWindowCleanup::vtkOutputWindowCleanup()
{
}
vtkOutputWindowCleanup::~vtkOutputWindowCleanup()
{
// Destroy any remaining output window.
vtkOutputWindow::SetInstance(0);
}
vtkOutputWindow::vtkOutputWindow()
{
this->PromptUser = 0;
......@@ -139,15 +141,6 @@ vtkOutputWindow* vtkOutputWindow::GetInstance()
{
if(!vtkOutputWindow::Instance)
{
if (!vtkOutputWindow::CleanupCommandRegistered)
{
vtkCallbackCommand *cbc = vtkCallbackCommand::New();
cbc->SetCallback(CleanupOutputWindow);
vtkDebugLeaks::AddCleanupCommand(cbc);
cbc->Delete();
vtkOutputWindow::CleanupCommandRegistered = 1;
}
// Try the factory first
vtkOutputWindow::Instance = (vtkOutputWindow*)
vtkObjectFactory::CreateInstance("vtkOutputWindow");
......@@ -173,15 +166,6 @@ vtkOutputWindow* vtkOutputWindow::GetInstance()
void vtkOutputWindow::SetInstance(vtkOutputWindow* instance)
{
if (!vtkOutputWindow::CleanupCommandRegistered)
{
vtkCallbackCommand *cbc = vtkCallbackCommand::New();
cbc->SetCallback(CleanupOutputWindow);
vtkDebugLeaks::AddCleanupCommand(cbc);
cbc->Delete();
vtkOutputWindow::CleanupCommandRegistered = 1;
}
if (vtkOutputWindow::Instance==instance)
{
return;
......
......@@ -24,6 +24,18 @@
#include "vtkObject.h"
//BTX
class VTK_COMMON_EXPORT vtkOutputWindow;
class VTK_COMMON_EXPORT vtkOutputWindowCleanup
{
public:
vtkOutputWindowCleanup();
~vtkOutputWindowCleanup();
};
//ETX
class VTK_COMMON_EXPORT vtkOutputWindow : public vtkObject
{
public:
......@@ -63,6 +75,12 @@ public:
// messages.
vtkBooleanMacro(PromptUser,int);
vtkSetMacro(PromptUser, int);
//BTX
// use this as a way of memory management when the
// program exits the SmartPointer will be deleted which
// will delete the Instance singleton
static vtkOutputWindowCleanup Cleanup;
//ETX
protected:
vtkOutputWindow();
virtual ~vtkOutputWindow();
......@@ -70,7 +88,6 @@ protected:
private:
static vtkOutputWindow* Instance;
private:
static int CleanupCommandRegistered;
vtkOutputWindow(const vtkOutputWindow&); // Not implemented.
void operator=(const vtkOutputWindow&); // Not implemented.
};
......
......@@ -106,6 +106,7 @@ vtkInformationInformationVectorKey.cxx
vtkInformationIntegerKey.cxx
vtkInformationIntegerVectorKey.cxx
vtkInformationKey.cxx
vtkInformationKeyManager.cxx
vtkInformationKeyVectorKey.cxx
vtkInformationObjectBaseKey.cxx
vtkInformationStringKey.cxx
......@@ -243,6 +244,7 @@ vtkInformationInformationVectorKey
vtkInformationIntegerKey
vtkInformationIntegerVectorKey
vtkInformationKey
vtkInformationKeyManager
vtkInformationKeyVectorKey
vtkInformationObjectBaseKey
vtkInformationStringKey
......@@ -282,6 +284,7 @@ vtkViewport
SET_SOURCE_FILES_PROPERTIES(
vtkImageIterator.cxx
vtkImageProgressIterator.cxx
vtkInformationKeyManager.cxx
WRAP_EXCLUDE
)
......
......@@ -15,11 +15,10 @@
#include "vtkInformationDoubleVectorKey.h"
#include "vtkInformation.h" // For vtkErrorWithObjectMacro
#include "vtkDebugLeaks.h"
#include <vtkstd/vector>
vtkCxxRevisionMacro(vtkInformationDoubleVectorKey, "1.3");
vtkCxxRevisionMacro(vtkInformationDoubleVectorKey, "1.4");
//----------------------------------------------------------------------------
vtkInformationDoubleVectorKey
......@@ -83,9 +82,7 @@ void vtkInformationDoubleVectorKey::Set(vtkInformation* info, double* value,
}
vtkInformationDoubleVectorValue* v =
new vtkInformationDoubleVectorValue;
#ifdef VTK_DEBUG_LEAKS
vtkDebugLeaks::ConstructClass("vtkInformationDoubleVectorValue");
#endif
this->ConstructClass("vtkInformationDoubleVectorValue");
v->Value.insert(v->Value.begin(), value, value+length);
this->SetAsObjectBase(info, v);
v->Delete();
......
......@@ -14,9 +14,7 @@
=========================================================================*/
#include "vtkInformationIntegerKey.h"
#include "vtkDebugLeaks.h"
vtkCxxRevisionMacro(vtkInformationIntegerKey, "1.3");
vtkCxxRevisionMacro(vtkInformationIntegerKey, "1.4");
//----------------------------------------------------------------------------
vtkInformationIntegerKey::vtkInformationIntegerKey(const char* name, const char* location):
......@@ -57,9 +55,7 @@ void vtkInformationIntegerKey::Set(vtkInformation* info, int value)
{
// Allocate a new value.
vtkInformationIntegerValue* v = new vtkInformationIntegerValue;
#ifdef VTK_DEBUG_LEAKS
vtkDebugLeaks::ConstructClass("vtkInformationIntegerValue");
#endif
this->ConstructClass("vtkInformationIntegerValue");
v->Value = value;
this->SetAsObjectBase(info, v);
v->Delete();
......
......@@ -15,12 +15,11 @@
#include "vtkInformationIntegerVectorKey.h"
#include "vtkInformation.h" // For vtkErrorWithObjectMacro
#include "vtkDebugLeaks.h"
#include <vtkstd/algorithm>
#include <vtkstd/vector>
vtkCxxRevisionMacro(vtkInformationIntegerVectorKey, "1.4");
vtkCxxRevisionMacro(vtkInformationIntegerVectorKey, "1.5");
//----------------------------------------------------------------------------
vtkInformationIntegerVectorKey
......@@ -96,9 +95,7 @@ void vtkInformationIntegerVectorKey::Set(vtkInformation* info, int* value,
// Allocate a new value.
vtkInformationIntegerVectorValue* v =
new vtkInformationIntegerVectorValue;
#ifdef VTK_DEBUG_LEAKS
vtkDebugLeaks::ConstructClass("vtkInformationIntegerVectorValue");
#endif
this->ConstructClass("vtkInformationIntegerVectorValue");
v->Value.insert(v->Value.begin(), value, value+length);
this->SetAsObjectBase(info, v);
v->Delete();
......
......@@ -19,7 +19,7 @@
#include <vtkstd/vector>
vtkCxxRevisionMacro(vtkInformationKey, "1.5");
vtkCxxRevisionMacro(vtkInformationKey, "1.6");
class vtkInformationKeyToInformationFriendship
{
......@@ -36,17 +36,25 @@ public:
}
};
//----------------------------------------------------------------------------
// Purposely not initialized. ClassInitialize will handle it.
vtkstd::vector<vtkInformationKey*>* vtkInformationKeyInstances;
//----------------------------------------------------------------------------
vtkInformationKey::vtkInformationKey(const char* name, const char* location)
{
// Save the name and location.
this->Name = name;
this->Location = location;
// Register this instance for deletion by the singleton.
vtkInformationKeyInstances->push_back(this);
}
//----------------------------------------------------------------------------
vtkInformationKey::~vtkInformationKey()
{
this->SetReferenceCount(0);
}
//----------------------------------------------------------------------------
......@@ -56,13 +64,13 @@ void vtkInformationKey::PrintSelf(ostream& os, vtkIndent indent)
}
//----------------------------------------------------------------------------
void vtkInformationKey::UnRegister(vtkObjectBase *)
void vtkInformationKey::Register(vtkObjectBase*)
{
}
//----------------------------------------------------------------------------
void vtkInformationKey::UnRegister(vtkObjectBase*)
{
this->ReferenceCount--;
if (this->ReferenceCount <= 0)
{
delete this;
}
}
//----------------------------------------------------------------------------
......@@ -101,3 +109,42 @@ void vtkInformationKey::Report(vtkInformation*, vtkGarbageCollector*)
{
// Report nothing by default.
}
//----------------------------------------------------------------------------
#ifdef VTK_DEBUG_LEAKS
void vtkInformationKey::ConstructClass(const char* name)
{
vtkDebugLeaks::ConstructClass(name);
}
#else
void vtkInformationKey::ConstructClass(const char*)
{
}
#endif
//----------------------------------------------------------------------------
void vtkInformationKey::ClassInitialize()
{
// Allocate the singleton storing pointers to all information keys.
vtkInformationKeyInstances = new vtkstd::vector<vtkInformationKey*>;
}
//----------------------------------------------------------------------------
void vtkInformationKey::ClassFinalize()
{
if(vtkInformationKeyInstances)
{
// Delete all information keys.
for(vtkstd::vector<vtkInformationKey*>::iterator i =
vtkInformationKeyInstances->begin();
i != vtkInformationKeyInstances->end(); ++i)
{
vtkInformationKey* key = *i;
delete key;
}
// Delete the singleton storing pointers to all information keys.
delete vtkInformationKeyInstances;
vtkInformationKeyInstances = 0;
}
}
......@@ -28,7 +28,7 @@
#include "vtkObjectBase.h"
#include "vtkObject.h" // Need vtkTypeRevisionMacro
#include "vtkSmartPointer.h" // Needed for vtkInformationKeyMacro
#include "vtkInformationKeyManager.h" // Needed for proper singleton initialization
class vtkInformation;
......@@ -38,14 +38,12 @@ public:
vtkTypeRevisionMacro(vtkInformationKey,vtkObjectBase);
void PrintSelf(ostream& os, vtkIndent indent);
// // Description:
// // Prevent normal vtkObject reference counting behavior.
// virtual void Register(vtkObjectBase*);
// Description:
// Prevent normal vtkObject reference counting behavior.
virtual void Register(vtkObjectBase*);
// Description:
// Do not participate in vtkDebugLeaks. These objects are created
// within objects that are global instantiations. They may be destroyed
// after vtkDebugLeaks::CriticalSection.
// Prevent normal vtkObject reference counting behavior.
virtual void UnRegister(vtkObjectBase*);
// Description:
......@@ -90,6 +88,9 @@ protected:
void SetAsObjectBase(vtkInformation* info, vtkObjectBase* value);
vtkObjectBase* GetAsObjectBase(vtkInformation* info);
// Helper for debug leaks support.
void ConstructClass(const char*);
// Static key instance management methods.
static void ClassInitialize();
static void ClassFinalize();
......@@ -106,15 +107,13 @@ private:
// Macros to define an information key instance in a C++ source file.
// The corresponding method declaration must appear in the class
// definition in the header file.
#define vtkInformationKeyMacro(CLASS, NAME, type) \
static vtkSmartPointer<vtkInformation##type##Key> CLASS##_##NAME \
(new vtkInformation##type##Key(#NAME, #CLASS), \
vtkSmartPointerBase::NoReference()); \
vtkInformation##type##Key* CLASS::NAME() {return CLASS##_##NAME.GetPointer();}
#define vtkInformationKeyMacro(CLASS, NAME, type) \
static vtkInformation##type##Key* CLASS##_##NAME = \
new vtkInformation##type##Key(#NAME, #CLASS); \
vtkInformation##type##Key* CLASS::NAME() { return CLASS##_##NAME; }
#define vtkInformationKeyRestrictedMacro(CLASS, NAME, type, required) \
static vtkSmartPointer<vtkInformation##type##Key> CLASS##_##NAME \
(new vtkInformation##type##Key(#NAME, #CLASS, required), \
vtkSmartPointerBase::NoReference()); \
vtkInformation##type##Key* CLASS::NAME() {return CLASS##_##NAME.GetPointer();}
static vtkInformation##type##Key* CLASS##_##NAME = \
new vtkInformation##type##Key(#NAME, #CLASS, required); \
vtkInformation##type##Key* CLASS::NAME() { return CLASS##_##NAME; }
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInformationKeyManager.cxx
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.
=========================================================================*/
#include "vtkInformationKeyManager.h"
#include "vtkInformationKey.h"
// Must NOT be initialized. Default initialization to zero is
// necessary.
unsigned int vtkInformationKeyManagerCount;
vtkInformationKeyManager::vtkInformationKeyManager()
{
if(++vtkInformationKeyManagerCount == 1)
{
vtkInformationKey::ClassInitialize();
}
}
vtkInformationKeyManager::~vtkInformationKeyManager()
{
if(--vtkInformationKeyManagerCount == 0)
{
vtkInformationKey::ClassFinalize();
}
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInformationKeyManager.h
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 vtkInformationKeyManager - Manages the vtkInformationKey singleton.
// .SECTION Description
// vtkInformationKeyManager should be included in any translation unit
// that will use vtkInformationKey or that implements the singleton
// pattern. It makes sure that the vtkInformationKey singleton is created
// before and destroyed after it is used.
#ifndef __vtkInformationKeyManager_h
#define __vtkInformationKeyManager_h
#include "vtkSystemIncludes.h"
class VTK_FILTERING_EXPORT vtkInformationKeyManager
{
public:
vtkInformationKeyManager();
~vtkInformationKeyManager();
};
// This instance will show up in any translation unit that uses
// vtkInformationKey or that has a singleton. It will make sure
// vtkInformationKey is initialized before and destroyed after it is
// used.
static vtkInformationKeyManager vtkInformationKeyManagerInstance;
#endif
......@@ -14,10 +14,9 @@
=========================================================================*/
#include "vtkInformationKeyVectorKey.h"
#include "vtkDebugLeaks.h"
#include <vtkstd/vector>
vtkCxxRevisionMacro(vtkInformationKeyVectorKey, "1.2");
vtkCxxRevisionMacro(vtkInformationKeyVectorKey, "1.3");
//----------------------------------------------------------------------------
vtkInformationKeyVectorKey::vtkInformationKeyVectorKey(const char* name, const char* location):
......@@ -69,9 +68,7 @@ void vtkInformationKeyVectorKey::Set(vtkInformation* info,
{
vtkInformationKeyVectorValue* v =
new vtkInformationKeyVectorValue;
#ifdef VTK_DEBUG_LEAKS
vtkDebugLeaks::ConstructClass("vtkInformationKeyVectorValue");
#endif
this->ConstructClass("vtkInformationKeyVectorValue");
v->Value.insert(v->Value.begin(), value, value+length);
this->SetAsObjectBase(info, v);
v->Delete();
......
......@@ -14,11 +14,9 @@
=========================================================================*/
#include "vtkInformationStringKey.h"
#include "vtkDebugLeaks.h"
#include <vtkstd/string>
vtkCxxRevisionMacro(vtkInformationStringKey, "1.2");
vtkCxxRevisionMacro(vtkInformationStringKey, "1.3");
//----------------------------------------------------------------------------
vtkInformationStringKey::vtkInformationStringKey(const char* name, const char* location):
......@@ -51,9 +49,7 @@ void vtkInformationStringKey::Set(vtkInformation* info, const char* value)
if(value)
{
vtkInformationStringValue* v = new vtkInformationStringValue;
#ifdef VTK_DEBUG_LEAKS
vtkDebugLeaks::ConstructClass("vtkInformationStringValue");
#endif
this->ConstructClass("vtkInformationStringValue");
v->Value = value;
this->SetAsObjectBase(info, v);
v->Delete();
......
......@@ -14,9 +14,7 @@
=========================================================================*/
#include "vtkInformationUnsignedLongKey.h"
#include "vtkDebugLeaks.h"
vtkCxxRevisionMacro(vtkInformationUnsignedLongKey, "1.3");
vtkCxxRevisionMacro(vtkInformationUnsignedLongKey, "1.4");
//----------------------------------------------------------------------------