Leaked source code of windows server 2003
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.

116 lines
2.6 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name :
  4. smartptr.pp
  5. Abstract:
  6. Smart pointers and reference counting
  7. Revision History:
  8. --*/
  9. #include <precom.h>
  10. #define TRC_FILE "smartptr"
  11. #include "smartptr.h"
  12. //
  13. // Stack traces for all references in debug build.
  14. //
  15. #if DBG
  16. DWORD RefCount::_dwReferenceTraceIndex = 0xFFFFFFFF;
  17. ReferenceTraceRecord
  18. RefCount::_TraceRecordList[kReferenceTraceMask + 1];
  19. #endif
  20. #if DBG
  21. void RefCount::RecordReferenceStack(LONG refs, DRSTRING ClassName)
  22. {
  23. DWORD index;
  24. DC_BEGIN_FN("RefCount::RecordReferenceStack");
  25. //
  26. // The masking does the wrapping automatically, while keeping
  27. // the operation atomic using InterlockedIncrement
  28. //
  29. // Win95 InterlockedIncrement() difference.
  30. InterlockedIncrement((PLONG)&_dwReferenceTraceIndex);
  31. index = _dwReferenceTraceIndex & kReferenceTraceMask;
  32. _TraceRecordList[index].ClassName = ClassName;
  33. _TraceRecordList[index].pRefCount = this;
  34. _TraceRecordList[index].refs = refs;
  35. RtlZeroMemory(_TraceRecordList[index].Stack,
  36. sizeof(_TraceRecordList[index].Stack));
  37. /* TODO: Figure out which lib this is in.
  38. GetStackTrace(1,
  39. kdwStackSize,
  40. _TraceRecordList[index].Stack,
  41. &hash);
  42. */
  43. DC_END_FN();
  44. }
  45. #endif // DBG
  46. RefCount::~RefCount()
  47. {
  48. DC_BEGIN_FN("RefCount::~RefCount");
  49. ASSERT(_crefs == 0);
  50. TRC_DBG((TB, _T("RefCount object deleted(%d)"), _crefs));
  51. DC_END_FN()
  52. }
  53. void RefCount::AddRef(void)
  54. {
  55. LONG crefs = InterlockedIncrement(&_crefs);
  56. DC_BEGIN_FN("RefCount::AddRef");
  57. ASSERT(crefs > 0);
  58. RecordReferenceStack(_crefs, ClassName());
  59. TRC_DBG((TB, _T("AddRef object type %s to %d"), ClassName(),
  60. _crefs));
  61. DC_END_FN();
  62. }
  63. void RefCount::Release(void)
  64. {
  65. LONG crefs;
  66. DRSTRING className = ClassName();
  67. DC_BEGIN_FN("RefCount::Release");
  68. ASSERT(_crefs > 0);
  69. crefs = InterlockedDecrement(&_crefs);
  70. //
  71. // It's not thread safe here, so we can't reference class name function
  72. // we have to save the class name string
  73. //
  74. RecordReferenceStack(_crefs, className);
  75. if (crefs == 0)
  76. {
  77. TRC_DBG((TB, _T("Deleting RefCount object type %s"),
  78. className));
  79. delete this;
  80. } else {
  81. TRC_DBG((TB, _T("Releasing object type %s to %d"),
  82. className, crefs));
  83. }
  84. DC_END_FN();
  85. }