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.

200 lines
4.3 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name :
  4. smartptr.h
  5. Abstract:
  6. Smart pointers and reference counting
  7. Revision History:
  8. --*/
  9. #pragma once
  10. #include "drobject.h"
  11. #include <atrcapi.h>
  12. const DWORD kdwStackSize = 10;
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif // __cplusplus
  16. #if defined(_X86_)
  17. USHORT
  18. GetStackTrace(
  19. IN ULONG FramesToSkip,
  20. IN ULONG FramesToCapture,
  21. OUT PVOID *BackTrace,
  22. OUT PULONG BackTraceHash);
  23. #else
  24. USHORT __inline GetStackTrace(
  25. IN ULONG FramesToSkip,
  26. IN ULONG FramesToCapture,
  27. OUT PVOID *BackTrace,
  28. OUT PULONG BackTraceHash)
  29. {
  30. return 0;
  31. UNREFERENCED_PARAMETER(FramesToSkip);
  32. UNREFERENCED_PARAMETER(FramesToCapture);
  33. UNREFERENCED_PARAMETER(BackTrace);
  34. UNREFERENCED_PARAMETER(BackTraceHash);
  35. }
  36. #endif // _X86_
  37. #ifdef __cplusplus
  38. }
  39. #endif
  40. #if DBG
  41. typedef struct tagReferenceTraceRecord {
  42. PVOID Stack[kdwStackSize];
  43. class RefCount *pRefCount;
  44. LPTSTR ClassName;
  45. LONG refs;
  46. } ReferenceTraceRecord;
  47. const DWORD kReferenceTraceMask = 0x3FF;
  48. #endif
  49. ///////////////////////////////////////////////////////////////
  50. //
  51. // RefCount
  52. //
  53. // Referenced counted objects must derive themselves from this
  54. // parent.
  55. //
  56. class RefCount : public DrObject
  57. {
  58. private:
  59. LONG _crefs;
  60. //
  61. // Track all open references in debug builds.
  62. //
  63. #if DBG
  64. static DWORD _dwReferenceTraceIndex;
  65. static ReferenceTraceRecord _TraceRecordList[kReferenceTraceMask + 1];
  66. void RecordReferenceStack(LONG refs, DRSTRING className);
  67. #else
  68. #define RecordReferenceStack(refs, className)
  69. #endif
  70. public:
  71. //
  72. // Constructor/Destructor
  73. //
  74. RefCount(void) : _crefs(0) { }
  75. virtual ~RefCount();
  76. //
  77. // Reference Counting Functions
  78. //
  79. void AddRef(void);
  80. void Release(void);
  81. };
  82. ///////////////////////////////////////////////////////////////
  83. //
  84. // SmartPtr
  85. //
  86. // Smart pointer template class.
  87. //
  88. template <class T> class SmartPtr {
  89. T* p;
  90. public:
  91. SmartPtr()
  92. {
  93. p = NULL;
  94. }
  95. SmartPtr(SmartPtr<T> &sp)
  96. {
  97. p = sp;
  98. if (p != NULL) {
  99. p->AddRef();
  100. }
  101. }
  102. SmartPtr(T* p_) : p(p_)
  103. {
  104. if (p != NULL) {
  105. p->AddRef();
  106. }
  107. }
  108. ~SmartPtr(void)
  109. {
  110. if ( p != NULL) {
  111. p->Release();
  112. }
  113. }
  114. inline T* operator->(void)
  115. {
  116. DC_BEGIN_FN("SmartPtr::operator->");
  117. // No referencing needed to access a member
  118. ASSERT(p != NULL);
  119. DC_END_FN();
  120. return p;
  121. }
  122. inline SmartPtr& operator=(SmartPtr<T> &p_)
  123. {
  124. // Referencing comes from using the other operator
  125. return operator=((T *) p_);
  126. }
  127. inline T& operator*(void)
  128. {
  129. DC_BEGIN_FN("SmartPtr::operator*");
  130. // No referencing needed to derefence
  131. ASSERT(p != NULL);
  132. DC_END_FN();
  133. return *p;
  134. }
  135. inline operator T*(void)
  136. {
  137. // The assignee is responsible for doing the AddRef,
  138. // and in the SmartPtr case, does
  139. return p;
  140. }
  141. inline int operator==(const SmartPtr<T> &p_) const
  142. {
  143. // The cast doesn't reference, so we can just do the compare
  144. return ((T*)p_ == p);
  145. }
  146. inline int operator==(const void *p_) const
  147. {
  148. // The cast doesn't reference, so we can just do the compare
  149. return ((T*)p_ == p);
  150. }
  151. inline int operator!=(const SmartPtr<T> &p_) const
  152. {
  153. // The cast doesn't reference, so we can just do the compare
  154. return ((T*)p_ != p);
  155. }
  156. inline int operator!=(const void *p_) const
  157. {
  158. // The cast doesn't reference, so we can just do the compare
  159. return ((T*)p_ != p);
  160. }
  161. inline int operator!()
  162. {
  163. return !p;
  164. }
  165. SmartPtr& operator=(T* p_) {
  166. if (p != NULL) {
  167. // Remove our reference to the old one
  168. p->Release();
  169. }
  170. p = p_;
  171. if (p != NULL) {
  172. // Add our reference to the new one
  173. p->AddRef();
  174. }
  175. return *this;
  176. }
  177. };