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.

229 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. safelock.h
  5. Abstract:
  6. "safe lock" collection of routines
  7. This code is a debug-only replacement for APIs dealing with
  8. critical sections and resources. It is essentially a thin
  9. wrapper around those routines that ensures proper ordering
  10. of locks and helps catch potential deadlock situations.
  11. The code will generate debug spew (and optionally assert)
  12. when locks are acquired outside of the given order.
  13. Utilizing this code will have zero impact on the FRE builds
  14. and negligible impact on DBG builds (as it is lock- and
  15. contention-free)
  16. Here is how you use it:
  17. o #include <safelock.h>
  18. o determine the lock order for your routine and add an enum
  19. such as:
  20. typedef enum {
  21. LockTypeA,
  22. LockTypeB,
  23. LockTypeC
  24. } MY_ENUM;
  25. The code will ensure that, for instance, LockTypeA
  26. is not acquired with LockTypeC held, unless that thread
  27. already holds LockTypeA.
  28. o Once per process initialization, call the SafeLockInit()
  29. routine. This routine should only be called in checked
  30. builds.
  31. o replace every declaration of RTL_CRITICAL_SECTION
  32. with SAFE_CRITICAL_SECTION
  33. o replace every declaration of RTL_RESOURCE
  34. with SAFE_RESOURCE
  35. o replace every call to RtlEnterCriticalSection with
  36. SafeEnterCriticalSection (similary for RtlLeaveCriticalSection
  37. and other Rtl* calls involving RTL_CRITICAL_SECTION)
  38. o replace every call to RtlAcquireResource with
  39. SafeAcquireResource (similarly for RtlReleaseResource and
  40. other Rtl* calls involving RTL_RESOURCE)
  41. o RtlInitializeCriticalSection and RtlInitializeResource
  42. are replaced with SafeEnterCriticalSection and
  43. SafeInitializeResource and take one additional parameter -
  44. the enum value associated with the critical section:
  45. e.g. replace
  46. RtlInitializeCriticalSection( &critsecA );
  47. with
  48. SafeInitializeCriticalSection( &critsecA, LockTypeA );
  49. --*/
  50. #ifndef __SAFELOCK_H
  51. #define __SAFELOCK_H
  52. #include <nturtl.h>
  53. #ifdef DBG
  54. NTSTATUS
  55. SafeLockInit(
  56. IN DWORD MaxLocks,
  57. IN BOOL AssertOnErrors
  58. );
  59. NTSTATUS
  60. SafeLockCleanup(
  61. );
  62. typedef struct _SAFE_CRITICAL_SECTION {
  63. RTL_CRITICAL_SECTION CriticalSection;
  64. LONG Enum;
  65. } SAFE_CRITICAL_SECTION, *PSAFE_CRITICAL_SECTION;
  66. NTSTATUS
  67. SafeEnterCriticalSection(
  68. PSAFE_CRITICAL_SECTION SafeCriticalSection
  69. );
  70. NTSTATUS
  71. SafeLeaveCriticalSection(
  72. PSAFE_CRITICAL_SECTION SafeCriticalSection
  73. );
  74. BOOLEAN
  75. SafeTryEnterCriticalSection(
  76. PSAFE_CRITICAL_SECTION SafeCriticalSection
  77. );
  78. NTSTATUS
  79. SafeInitializeCriticalSection(
  80. PSAFE_CRITICAL_SECTION SafeCriticalSection,
  81. DWORD Enum
  82. );
  83. NTSTATUS
  84. SafeInitializeCriticalSectionAndSpinCount(
  85. PSAFE_CRITICAL_SECTION CriticalSection,
  86. ULONG SpinCount,
  87. DWORD Enum
  88. );
  89. ULONG
  90. SafeSetCriticalSectionSpinCount(
  91. PSAFE_CRITICAL_SECTION CriticalSection,
  92. ULONG SpinCount
  93. );
  94. NTSTATUS
  95. SafeDeleteCriticalSection(
  96. PSAFE_CRITICAL_SECTION CriticalSection
  97. );
  98. #define SafeCritsecLockCount( _critsec ) ((_critsec)->CriticalSection.LockCount )
  99. typedef struct _SAFE_RESOURCE {
  100. RTL_RESOURCE Resource;
  101. LONG Enum;
  102. } SAFE_RESOURCE, *PSAFE_RESOURCE;
  103. VOID
  104. SafeInitializeResource(
  105. PSAFE_RESOURCE Resource,
  106. DWORD Enum
  107. );
  108. BOOLEAN
  109. SafeAcquireResourceShared(
  110. PSAFE_RESOURCE Resource,
  111. BOOLEAN Wait
  112. );
  113. BOOLEAN
  114. SafeAcquireResourceExclusive(
  115. PSAFE_RESOURCE Resource,
  116. BOOLEAN Wait
  117. );
  118. VOID
  119. SafeReleaseResource(
  120. PSAFE_RESOURCE Resource
  121. );
  122. VOID
  123. SafeConvertSharedToExclusive(
  124. PSAFE_RESOURCE Resource
  125. );
  126. VOID
  127. SafeConvertExclusiveToShared(
  128. PSAFE_RESOURCE Resource
  129. );
  130. VOID
  131. NTAPI
  132. SafeDeleteResource (
  133. PSAFE_RESOURCE Resource
  134. );
  135. #define SafeEnterResourceCritsec( _resrc ) RtlEnterCriticalSection( &(_resrc)->Resource.CriticalSection )
  136. #define SafeLeaveResourceCritsec( _resrc ) RtlLeaveCriticalSection( &(_resrc)->Resource.CriticalSection )
  137. #define SafeNumberOfActive( _resrc ) ((_resrc)->Resource.NumberOfActive )
  138. #define SafeNumberOfWaitingShared( _resrc ) ((_resrc)->Resource.NumberOfWaitingShared )
  139. #define SafeNumberOfWaitingExclusive( _resrc ) ((_resrc)->Resource.NumberOfWaitingExclusive )
  140. #else
  141. #define SAFE_CRITICAL_SECTION RTL_CRITICAL_SECTION
  142. #define PSAFE_CRITICAL_SECTION PRTL_CRITICAL_SECTION
  143. #define SafeEnterCriticalSection RtlEnterCriticalSection
  144. #define SafeLeaveCriticalSection RtlLeaveCriticalSection
  145. #define SafeTryEnterCriticalSection RtlTryEnterCriticalSection
  146. #define SafeInitializeCriticalSection( _cs, _enum ) RtlInitializeCriticalSection( _cs )
  147. #define SafeInitializeCriticalSectionAndSpinCount( _cs, _count, _enum ) RtlInitializeCriticalSectionAndSpinCount( _cs, _count )
  148. #define SafeSetCriticalSectionSpinCount RtlSetCriticalSectionSpinCount
  149. #define SafeDeleteCriticalSection RtlDeleteCriticalSection
  150. #define SafeCritsecLockCount( _critsec ) ((_critsec)->LockCount )
  151. #define SAFE_RESOURCE RTL_RESOURCE
  152. #define PSAFE_RESOURCE PRTL_RESOURCE
  153. #define SafeInitializeResource( _res, _enum ) RtlInitializeResource( _res )
  154. #define SafeAcquireResourceShared RtlAcquireResourceShared
  155. #define SafeAcquireResourceExclusive RtlAcquireResourceExclusive
  156. #define SafeReleaseResource RtlReleaseResource
  157. #define SafeConvertSharedToExclusive RtlConvertSharedToExclusive
  158. #define SafeConvertExclusiveToShared RtlConvertExclusiveToShared
  159. #define SafeDeleteResource RtlDeleteResource
  160. #define SafeEnterResourceCritsec( _resrc ) RtlEnterCriticalSection( &(_resrc)->CriticalSection )
  161. #define SafeLeaveResourceCritsec( _resrc ) RtlLeaveCriticalSection( &(_resrc)->CriticalSection )
  162. #define SafeNumberOfActive( _resrc ) ((_resrc)->NumberOfActive )
  163. #define SafeNumberOfWaitingShared( _resrc ) ((_resrc)->NumberOfWaitingShared )
  164. #define SafeNumberOfWaitingExclusive( _resrc ) ((_resrc)->NumberOfWaitingExclusive )
  165. #endif
  166. #endif // __SAFELOCK_H