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.
95 lines
2.2 KiB
95 lines
2.2 KiB
/*++
|
|
|
|
Copyright (c) 1998-2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
smartptr.pp
|
|
|
|
Abstract:
|
|
|
|
Smart pointers and reference counting
|
|
|
|
Revision History:
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#define TRC_FILE "smartptr"
|
|
#include "trc.h"
|
|
|
|
#if DBG
|
|
void RefCount::RecordReferenceStack(LONG refs)
|
|
{
|
|
ULONG hash;
|
|
DWORD index;
|
|
|
|
BEGIN_FN("RefCount::RecordReferenceStack");
|
|
|
|
//
|
|
// The masking does the wrapping automatically, while keeping
|
|
// the operation atomic using InterlockedIncrement
|
|
//
|
|
|
|
index = InterlockedIncrement((PLONG)&_dwReferenceTraceIndex) & kReferenceTraceMask;
|
|
|
|
_TraceRecordList[index].ClassName = _ClassName;
|
|
_TraceRecordList[index].pRefCount = this;
|
|
_TraceRecordList[index].refs = refs;
|
|
|
|
|
|
RtlZeroMemory(_TraceRecordList[index].Stack,
|
|
sizeof(_TraceRecordList[index].Stack));
|
|
|
|
RtlCaptureStackBackTrace(1,
|
|
kdwStackSize,
|
|
_TraceRecordList[index].Stack,
|
|
&hash);
|
|
}
|
|
#endif // DBG
|
|
|
|
RefCount::~RefCount()
|
|
{
|
|
BEGIN_FN("RefCount::~RefCount");
|
|
ASSERT(_crefs == 0);
|
|
TRC_DBG((TB, "RefCount object deleted(%p, cref=%d)", this, _crefs));
|
|
}
|
|
|
|
void RefCount::AddRef(void)
|
|
{
|
|
LONG crefs = InterlockedIncrement(&_crefs);
|
|
|
|
BEGIN_FN("RefCount::AddRef");
|
|
ASSERT(crefs > 0);
|
|
RecordReferenceStack(crefs);
|
|
TRC_DBG((TB, "AddRef object type %s (%p) to %d", _ClassName, this,
|
|
crefs));
|
|
}
|
|
|
|
void RefCount::Release(void)
|
|
{
|
|
LONG crefs;
|
|
#if DBG
|
|
PCHAR ClassName = _ClassName;
|
|
#endif
|
|
|
|
BEGIN_FN("RefCount::Release");
|
|
|
|
ASSERT(_crefs > 0);
|
|
|
|
//
|
|
// The trace below is not thread safe to access class member
|
|
// So we need to make a copy of the class name
|
|
//
|
|
RecordReferenceStack(_crefs);
|
|
crefs = InterlockedDecrement(&_crefs);
|
|
|
|
if (crefs == 0)
|
|
{
|
|
TRC_DBG((TB, "Deleting RefCount object type %s (%p)",
|
|
ClassName, this));
|
|
delete this;
|
|
} else {
|
|
TRC_DBG((TB, "Releasing object type %s (%p) to %d",
|
|
ClassName, this, crefs));
|
|
}
|
|
}
|