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.

194 lines
4.3 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. refcnt.c
  5. Abstract:
  6. This module exports Reference Counting support functions. By
  7. including a Reference Count Control Block (REF_CNT) in a
  8. dynamic type, and using this API, a Reference scheme can be
  9. implemented for that type.
  10. Author:
  11. Edward Buchwalter (v-edbuc) 14-Aug-1996
  12. Revision History:
  13. Shreedhar Madhavapeddi (ShreeM) 16-April-1999 Adapted for NT and GPC by ShreeM\MBert.
  14. Rajesh Sundaram (rajeshsu) 05-Aug-1999 Adapted for psched.
  15. --*/
  16. //
  17. // Include Files
  18. //
  19. #include "psched.h"
  20. #pragma hdrstop
  21. #define EXPAND_TAG(t) ((CHAR *)(&Tag))[0],((CHAR *)(&Tag))[1],((CHAR *)(&Tag))[2],((CHAR *)(&Tag))[3]
  22. VOID
  23. ReferenceInit
  24. (
  25. IN PREF_CNT pRefCnt,
  26. PVOID InstanceHandle,
  27. VOID (*DeleteHandler)( PVOID , BOOLEAN)
  28. )
  29. /*++
  30. Routine Description:
  31. ReferenceInit initializes and adds one reference to the
  32. supplied Reference Control Block. If provided, an instance
  33. handle and delete handler are saved for use by the ReferenceRemove
  34. function when all references to the instance are removed.
  35. Arguments:
  36. pRefCnt - pointer to uninitialized Reference Control Block
  37. InstanceHandle - handle to the managed instance.
  38. DeleteHandler - pointer to delete function, NULL is OK.
  39. Return Value:
  40. The function's value is VOID.
  41. --*/
  42. {
  43. ASSERT( pRefCnt );
  44. // Set the reference to 1 and save the instance
  45. // handle and the delete handler.
  46. pRefCnt->Count = 0;
  47. pRefCnt->Instance = InstanceHandle;
  48. pRefCnt->DeleteHandler = DeleteHandler;
  49. #if DBG
  50. pRefCnt->Sig = REF_SIG;
  51. RtlZeroMemory(pRefCnt->Tags, sizeof(REF_TAG) * TAG_CNT);
  52. pRefCnt->Tags[0].Tag = 'LTOT';
  53. CTEInitLock(&pRefCnt->Lock);
  54. #endif
  55. }
  56. #if DBG
  57. VOID
  58. ReferenceAddDbg(PREF_CNT pRefCnt, ULONG Tag)
  59. {
  60. int i;
  61. CTELockHandle hLock;
  62. int TotalPerArray = 0;
  63. ASSERT(pRefCnt->Sig == REF_SIG);
  64. CTEGetLock(&pRefCnt->Lock, &hLock);
  65. for (i = 1; i < TAG_CNT; i++)
  66. {
  67. if (pRefCnt->Tags[i].Tag == 0 || pRefCnt->Tags[i].Tag == Tag)
  68. {
  69. pRefCnt->Tags[i].Tag = Tag;
  70. InterlockedIncrement(&pRefCnt->Tags[i].Count);
  71. break;
  72. }
  73. }
  74. ASSERT(i < TAG_CNT);
  75. InterlockedIncrement(&pRefCnt->Tags[0].Count);
  76. InterlockedIncrement(&pRefCnt->Count);
  77. ASSERT(pRefCnt->Tags[0].Count == pRefCnt->Count);
  78. // sanity check
  79. /*
  80. for (i = 1; i < TAG_CNT; i++)
  81. {
  82. if (pRefCnt->Tags[i].Tag != 0)
  83. {
  84. TotalPerArray += pRefCnt->Tags[i].Count;
  85. continue;
  86. }
  87. }
  88. ASSERT(TotalPerArray == pRefCnt->Tags[0].Count);
  89. if (TotalPerArray != pRefCnt->Tags[0].Count)
  90. {
  91. DbgBreakPoint();
  92. }
  93. */
  94. CTEFreeLock(&pRefCnt->Lock, hLock);
  95. }
  96. VOID
  97. ReferenceRemoveDbg(PREF_CNT pRefCnt, BOOLEAN LockHeld, ULONG Tag)
  98. {
  99. int i;
  100. CTELockHandle hLock;
  101. int TotalPerArray = 0;
  102. BOOLEAN FoundIt = FALSE;
  103. ASSERT(pRefCnt->Sig == REF_SIG);
  104. CTEGetLock(&pRefCnt->Lock, &hLock);
  105. for (i = 1; i < TAG_CNT; i++)
  106. {
  107. if (pRefCnt->Tags[i].Tag == Tag)
  108. {
  109. FoundIt = TRUE;
  110. ASSERT(pRefCnt->Tags[i].Count > 0);
  111. InterlockedDecrement(&pRefCnt->Tags[i].Count);
  112. if (pRefCnt->Tags[i].Count == 0)
  113. pRefCnt->Tags[i].Tag = Tag;
  114. break;
  115. }
  116. }
  117. ASSERT(FoundIt);
  118. ASSERT(pRefCnt->Tags[0].Count > 0);
  119. ASSERT(pRefCnt->Tags[0].Count == pRefCnt->Count);
  120. InterlockedDecrement(&pRefCnt->Tags[0].Count);
  121. if (InterlockedDecrement(&pRefCnt->Count) > 0 )
  122. {
  123. CTEFreeLock(&pRefCnt->Lock, hLock);
  124. }
  125. else if (pRefCnt->DeleteHandler)
  126. {
  127. CTEFreeLock(&pRefCnt->Lock, hLock);
  128. (pRefCnt->DeleteHandler)( pRefCnt->Instance, LockHeld );
  129. }
  130. else
  131. {
  132. CTEFreeLock(&pRefCnt->Lock, hLock);
  133. }
  134. }
  135. #endif