+++ /dev/null
-#include "stdafx.h"\r
-/*\r
-* Copyright (c) 2007-2010 SlimDX Group\r
-* \r
-* Permission is hereby granted, free of charge, to any person obtaining a copy\r
-* of this software and associated documentation files (the "Software"), to deal\r
-* in the Software without restriction, including without limitation the rights\r
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-* copies of the Software, and to permit persons to whom the Software is\r
-* furnished to do so, subject to the following conditions:\r
-* \r
-* The above copyright notice and this permission notice shall be included in\r
-* all copies or substantial portions of the Software.\r
-* \r
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-* THE SOFTWARE.\r
-*/\r
-\r
-#include "ObjectTable.h"\r
-#include "InternalHelpers.h"\r
-#include "ComObject.h"\r
-\r
-using namespace System;\r
-using namespace System::Threading;\r
-using namespace System::Globalization;\r
-using namespace System::Collections::ObjectModel;\r
-using namespace System::Collections::Generic;\r
-using namespace System::Diagnostics;\r
-\r
-namespace SlimDX\r
-{\r
- static ObjectTable::ObjectTable()\r
- {\r
- m_Table = gcnew Dictionary<IntPtr, ComObject^>();\r
- m_Ancillary = gcnew Dictionary<IntPtr, List<ComObject^>^>();\r
- m_SyncObject = gcnew Object();\r
-\r
- AppDomain::CurrentDomain->DomainUnload += gcnew System::EventHandler( OnExit );\r
- AppDomain::CurrentDomain->ProcessExit += gcnew System::EventHandler( OnExit );\r
- }\r
-\r
- ObjectTable::ObjectTable()\r
- {\r
- }\r
-\r
- void ObjectTable::OnExit( Object^ sender, EventArgs^ e )\r
- {\r
- SLIMDX_UNREFERENCED_PARAMETER(sender);\r
- SLIMDX_UNREFERENCED_PARAMETER(e);\r
-\r
- String^ leakString = ReportLeaks();\r
- Debug::Write( leakString );\r
- }\r
-\r
- ComObject^ ObjectTable::Find( IntPtr nativeObject )\r
- {\r
- Monitor::Enter( m_SyncObject );\r
- try\r
- {\r
- if( m_Table->ContainsKey( nativeObject ) )\r
- {\r
- return m_Table[nativeObject];\r
- }\r
-\r
- return nullptr;\r
- }\r
- finally\r
- {\r
- Monitor::Exit( m_SyncObject );\r
- }\r
- }\r
-\r
- bool ObjectTable::Contains( ComObject^ object )\r
- {\r
- Monitor::Enter( m_SyncObject );\r
- try\r
- {\r
- return m_Table->ContainsKey( object->ComPointer );\r
- }\r
- finally\r
- {\r
- Monitor::Exit( m_SyncObject );\r
- }\r
- }\r
-\r
- void ObjectTable::Add( ComObject^ object, ComObject^ owner )\r
- {\r
- if( object == nullptr )\r
- throw gcnew ArgumentNullException( "comObject" );\r
-\r
- // Record tracking information\r
- object->SetCreationTime( static_cast<int>( Configuration::Timer->ElapsedMilliseconds ) );\r
- if( Configuration::EnableObjectTracking )\r
- object->SetSource( gcnew StackTrace( 2, true ) );\r
-\r
- // Add to the table\r
- Monitor::Enter( m_SyncObject );\r
- try\r
- {\r
- m_Table->Add( object->ComPointer, object );\r
- \r
- if( owner != nullptr ) \r
- {\r
- if( !m_Ancillary->ContainsKey( owner->ComPointer ) )\r
- {\r
- m_Ancillary->Add( owner->ComPointer, gcnew List<ComObject^>() );\r
- }\r
- m_Ancillary[owner->ComPointer]->Add( object );\r
- }\r
- \r
- ObjectAdded( nullptr, gcnew ObjectTableEventArgs( object ) );\r
- }\r
- finally\r
- {\r
- Monitor::Exit( m_SyncObject );\r
- }\r
- }\r
-\r
- bool ObjectTable::Remove( ComObject^ object )\r
- {\r
- if( object == nullptr )\r
- throw gcnew ArgumentNullException( "comObject" );\r
-\r
- Monitor::Enter( m_SyncObject );\r
- try\r
- {\r
- if( !m_Table->ContainsKey( object->ComPointer ) )\r
- return false;\r
-\r
- m_Table->Remove( object->ComPointer );\r
- \r
- // If the object has ancillary objects, destroy them.\r
- if( m_Ancillary->ContainsKey( object->ComPointer ) )\r
- {\r
- for each( ComObject^ ancillary in m_Ancillary[object->ComPointer])\r
- {\r
- // By setting the owner to nullptr just before we release this object,\r
- // we prevent an exception being thrown about the inability to release\r
- // ancillary objects (since this delete call causes us to go through\r
- // the same machinery that users use to Dispose() objects, and they should\r
- // not be allowed to do that to ancillary objects).\r
- ancillary->Owner = nullptr;\r
- delete ancillary;\r
- }\r
- \r
- m_Ancillary[object->ComPointer]->Clear();\r
- }\r
- \r
- ObjectRemoved( nullptr, gcnew ObjectTableEventArgs( object ) );\r
- }\r
- finally\r
- {\r
- Monitor::Exit( m_SyncObject );\r
- }\r
- return true;\r
- }\r
-\r
- String^ ObjectTable::ReportLeaks()\r
- {\r
- String^ output = "";\r
-\r
- Monitor::Enter( m_SyncObject );\r
- try\r
- {\r
- for each( KeyValuePair<IntPtr, ComObject^> pair in m_Table )\r
- {\r
- output += String::Format( CultureInfo::InvariantCulture, "Object of type {0} was not disposed. Stack trace of object creation:\n", pair.Value->GetType() );\r
-\r
- if( pair.Value->CreationSource == nullptr )\r
- continue;\r
-\r
- for each( StackFrame^ frame in pair.Value->CreationSource->GetFrames() )\r
- {\r
- if( frame->GetFileLineNumber() == 0 )\r
- {\r
- // Compiler autogenerated functions and the like can cause stack frames with no info;\r
- // that's the only time the line number is 0 and since it's not a useful frame to see,\r
- // we'll skip it\r
- continue;\r
- }\r
-\r
- output += String::Format( CultureInfo::InvariantCulture, "\t{0}({1},{2}): {3}\n",\r
- frame->GetFileName(),\r
- frame->GetFileLineNumber(),\r
- frame->GetFileColumnNumber(),\r
- frame->GetMethod() );\r
- }\r
- }\r
-\r
- output += String::Format( CultureInfo::InvariantCulture, "Total of {0} objects still alive.\n", m_Table->Count );\r
- }\r
- finally\r
- {\r
- Monitor::Exit( m_SyncObject );\r
- }\r
- return output;\r
- }\r
-\r
- ReadOnlyCollection<ComObject^>^ ObjectTable::Objects::get()\r
- {\r
- return gcnew ReadOnlyCollection<ComObject^>( gcnew List<ComObject^>( m_Table->Values ) );\r
- }\r
-\r
- Object^ ObjectTable::SyncObject::get()\r
- {\r
- return m_SyncObject;\r
- }\r
-}
\ No newline at end of file