Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

# Tools/Xabsl2/yabsl/vsyabsl/common.cpp

Go to the documentation of this file.

    00001
    00002 /***************************************************************************
    00003          Copyright (c) Microsoft Corporation, All rights reserved.
    00004     This code sample is provided "AS IS" without warranty of any kind,
    00005     it is not recommended for use in a production environment.
    00006 ***************************************************************************/
    00007
    00008 #include "common.h"
    00009 #include <stdio.h>
    00010 #include <stdarg.h>
    00011
    00012 /*---------------------------------------------------------
    00013   Reference counting
    00014 -----------------------------------------------------------*/
    00015 ULONG IncRefCount( inout ULONG* refCount )
    00016 {
    00017   return (ULONG)InterlockedIncrement( (LONG*)refCount );
    00018 }
    00019
    00020 ULONG DecRefCount( inout ULONG* refCount )
    00021 {
    00022   return (ULONG)InterlockedDecrement( (LONG*)refCount );
    00023 }
    00024
    00025
    00026
    00027 /*---------------------------------------------------------
    00028   Debugging
    00029 -----------------------------------------------------------*/
    00030 static const char*      g_traceModuleName = NULL;
    00031 static CRITICAL_SECTION g_traceGuard;
    00032 static DWORD            g_traceThreadID;
    00033
    00034 void Trace( const char* format, ... )
    00035 {
    00036   va_list args;
    00037   va_start( args, format );
    00038
    00039   EnterCriticalSection( &g_traceGuard );
    00040
    00041   if (g_traceModuleName)
    00042   {
    00043     OutputDebugStringA(g_traceModuleName);
    00044     OutputDebugStringA( ": " );
    00045   }
    00046
    00047   char buffer[1024];
    00048
    00049   DWORD threadID = GetCurrentThreadId();
    00050   if (threadID != g_traceThreadID)
    00051   {
    00052     _snprintf( buffer, 1023, "tid 0x%x: ", threadID );
    00053     buffer[1023] = 0;
    00054     OutputDebugStringA(buffer);
    00055   }
    00056
    00057   _vsnprintf( buffer, 1024, format, args );
    00058   buffer[1023] = 0;
    00059   OutputDebugStringA(buffer);
    00060
    00061   OutputDebugStringA( "\n" );
    00062
    00063   LeaveCriticalSection( &g_traceGuard );
    00064
    00065   va_end( args );
    00066   return;
    00067 }
    00068
    00069
    00070 /*---------------------------------------------------------
    00071   Track object life times
    00072 -----------------------------------------------------------*/
    00073 struct ObjectInfo
    00074 {
    00075   ObjectInfo* next;
    00076   const char* name;
    00077   IUnknown*   obj;
    00078 };
    00079
    00080 static ObjectInfo*      objectList = NULL;
    00081
    00082 void TraceDumpObjects()
    00083 {
    00084   EnterCriticalSection( &g_traceGuard );
    00085
    00086   TRACE("live objects:");
    00087   for (ObjectInfo* objectInfo = objectList; objectInfo; objectInfo = objectInfo->next )
    00088   {
    00089     ULONG refCount = objectInfo->obj->AddRef();
    00090     if (refCount > 0)
    00091     {
    00092       objectInfo->obj->Release();
    00093       refCount--;
    00094     }
    00095     TRACE3( "  0x%x, refcount %u, %s", objectInfo->obj, refCount, objectInfo->name);
    00096   }
    00097
    00098   LeaveCriticalSection( &g_traceGuard );
    00099 }
    00100
    00101 void TraceInit( in const char* moduleName )
    00102 {
    00103   InitializeCriticalSection( &g_traceGuard );
    00104   g_traceThreadID     = GetCurrentThreadId();
    00105
    00106   g_traceModuleName = moduleName;
    00107   objectList        = NULL;
    00108
    00109 }
    00110
    00111 void TraceDone()
    00112 {
    00113   EnterCriticalSection( &g_traceGuard );
    00114
    00115   if (objectList)
    00116   {
    00117     TRACE( "found live objects:" );
    00118     TraceDumpObjects();
    00119   }
    00120
    00121   ObjectInfo* objectInfo;
    00122   ObjectInfo* objectNext;
    00123
    00124   objectInfo = objectList;
    00125   while (objectInfo)
    00126   {
    00127     objectNext = objectInfo->next;
    00128     FREE(objectInfo);
    00129     objectInfo = objectNext;
    00130   }
    00131
    00132   objectList = NULL;
    00133
    00134   LeaveCriticalSection( &g_traceGuard );
    00135   DeleteCriticalSection( &g_traceGuard );
    00136 }
    00137
    00138
    00139
    00140 void TraceCreate( const char* name, IUnknown* obj )
    00141 {
    00142   EnterCriticalSection( &g_traceGuard );
    00143
    00144   ObjectInfo* objectInfo = ALLOC(ObjectInfo);
    00145   if (!objectInfo) return;
    00146   if (!obj)
    00147   {
    00148     TRACE1("TraceCreate: creation of %s failed", name );
    00149     return;
    00150   }
    00151
    00152   TRACE2( "create %s at 0x%x", name, obj );
    00153   objectInfo->name = name;
    00154   objectInfo->obj  = obj;
    00155   objectInfo->next = objectList;
    00156   objectList       = objectInfo;
    00157
    00158   LeaveCriticalSection( &g_traceGuard );
    00159 }
    00160
    00161 void TraceDestroy( IUnknown* obj )
    00162 {
    00163   EnterCriticalSection( &g_traceGuard );
    00164
    00165   ObjectInfo* objectInfo;
    00166   ObjectInfo* objectPrev = NULL;
    00167
    00168   for (objectInfo = objectList; objectInfo; objectInfo = objectInfo->next)
    00169   {
    00170     if (objectInfo->obj == obj) break;
    00171     objectPrev = objectInfo;
    00172   }
    00173
    00174   if (!objectInfo)
    00175   {
    00176     TRACE1( "TraceDestroy: destroying unknown object at 0x%x", obj );
    00177   }
    00178   else
    00179   {
    00180     TRACE2( "destroy %s at 0x%8x", objectInfo->name, objectInfo->obj );
    00181     if (objectPrev)
    00182       objectPrev->next = objectInfo->next;
    00183     else
    00184       objectList = objectInfo->next;
    00185
    00186     FREE(objectInfo);
    00187   }
    00188
    00189   LeaveCriticalSection( &g_traceGuard );
    00190 }