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.

233 lines
7.9 KiB

  1. // Ruler
  2. // 1 2 3 4 5 6 7 8
  3. //345678901234567890123456789012345678901234567890123456789012345678901234567890
  4. /********************************************************************/
  5. /* */
  6. /* The standard layout. */
  7. /* */
  8. /* The standard layout for 'cpp' files in this code is as */
  9. /* follows: */
  10. /* */
  11. /* 1. Include files. */
  12. /* 2. Constants local to the class. */
  13. /* 3. Data structures local to the class. */
  14. /* 4. Data initializations. */
  15. /* 5. Static functions. */
  16. /* 6. Class functions. */
  17. /* */
  18. /* The constructor is typically the first function, class */
  19. /* member functions appear in alphabetical order with the */
  20. /* destructor appearing at the end of the file. Any section */
  21. /* or function this is not required is simply omitted. */
  22. /* */
  23. /********************************************************************/
  24. #include "LibraryPCH.hpp"
  25. #include "Globallock.hpp"
  26. /********************************************************************/
  27. /* */
  28. /* Class constructor. */
  29. /* */
  30. /* Create a new lock and initialize it. This call is not */
  31. /* thread safe and should only be made in a single thread */
  32. /* environment. */
  33. /* */
  34. /********************************************************************/
  35. GLOBALLOCK::GLOBALLOCK( CHAR *Name,SBIT32 NewMaxUsers )
  36. {
  37. //
  38. // Set the initial state.
  39. //
  40. if ( (Semaphore = CreateSemaphore( NULL,1,NewMaxUsers,Name )) == NULL )
  41. { Failure( "Global semaphore rejected by OS" ); }
  42. #ifdef ENABLE_LOCK_STATISTICS
  43. //
  44. // Zero the lock statistics.
  45. //
  46. TotalLocks = 0;
  47. TotalTimeouts = 0;
  48. #endif
  49. }
  50. /********************************************************************/
  51. /* */
  52. /* Claim the Globallock. */
  53. /* */
  54. /* Claim the lock if available else wait or exit. */
  55. /* */
  56. /********************************************************************/
  57. BOOLEAN GLOBALLOCK::ClaimLock( SBIT32 Sleep )
  58. {
  59. #ifdef ENABLE_RECURSIVE_LOCKS
  60. REGISTER SBIT32 ThreadId = GetThreadId();
  61. //
  62. // We may already own the spin lock. If so
  63. // we increment the recursive count. If not
  64. // we have to wait.
  65. //
  66. if ( Owner != ThreadId )
  67. {
  68. #endif
  69. //
  70. // Wait for the global lock.
  71. //
  72. if
  73. (
  74. WaitForSingleObject( Semaphore,Sleep )
  75. !=
  76. WAIT_OBJECT_0
  77. )
  78. {
  79. //
  80. // We failed to claim the lock due to
  81. // a timeout.
  82. //
  83. #ifdef ENABLE_LOCK_STATISTICS
  84. (VOID) AtomicIncrement( & TotalTimeouts );
  85. #endif
  86. return False;
  87. }
  88. #ifdef ENABLE_RECURSIVE_LOCKS
  89. //
  90. // Register the new owner of the lock.
  91. //
  92. NewExclusiveOwner( ThreadId );
  93. }
  94. else
  95. { Recursive ++; }
  96. #endif
  97. #ifdef ENABLE_LOCK_STATISTICS
  98. //
  99. // Update the statistics.
  100. //
  101. (VOID) AtomicIncrement( & TotalLocks );
  102. #endif
  103. return True;
  104. }
  105. #ifdef ENABLE_RECURSIVE_LOCKS
  106. /********************************************************************/
  107. /* */
  108. /* New exclusive owner. */
  109. /* */
  110. /* Delete the exclusive lock owner information. */
  111. /* */
  112. /********************************************************************/
  113. VOID GLOBALLOCK::DeleteExclusiveOwner( VOID )
  114. {
  115. #ifdef DEBUGGING
  116. if ( Owner != NULL )
  117. {
  118. #endif
  119. Owner = NULL;
  120. #ifdef DEBUGGING
  121. }
  122. else
  123. { Failure( "Globallock has no owner in DeleteExclusiveOwner" ); }
  124. #endif
  125. }
  126. /********************************************************************/
  127. /* */
  128. /* New exclusive owner. */
  129. /* */
  130. /* Register new exclusive lock owner information. */
  131. /* */
  132. /********************************************************************/
  133. VOID GLOBALLOCK::NewExclusiveOwner( SBIT32 NewOwner )
  134. {
  135. #ifdef DEBUGGING
  136. if ( Owner == NULL )
  137. {
  138. #endif
  139. Owner = NewOwner;
  140. #ifdef DEBUGGING
  141. }
  142. else
  143. { Failure( "Already exclusive in NewExclusiveOwner" ); }
  144. #endif
  145. }
  146. #endif
  147. /********************************************************************/
  148. /* */
  149. /* Release the spinlock. */
  150. /* */
  151. /* Release the lock and if needed wakeup any sleepers. */
  152. /* */
  153. /********************************************************************/
  154. VOID GLOBALLOCK::ReleaseLock( VOID )
  155. {
  156. #ifdef ENABLE_RECURSIVE_LOCKS
  157. //
  158. // When we have recursive lock calls we do not
  159. // release the lock until we have exited to the
  160. // top level.
  161. //
  162. if ( Recursive <= 0 )
  163. {
  164. //
  165. // Delete the exclusive owner information.
  166. //
  167. DeleteExclusiveOwner();
  168. #endif
  169. //
  170. // Release the global lock.
  171. //
  172. ReleaseSemaphore( Semaphore,1,NULL );
  173. #ifdef ENABLE_RECURSIVE_LOCKS
  174. }
  175. else
  176. { Recursive --; }
  177. #endif
  178. }
  179. /********************************************************************/
  180. /* */
  181. /* Class destructor. */
  182. /* */
  183. /* Destory a lock. This call is not thread safe and should */
  184. /* only be made in a single thread environment. */
  185. /* */
  186. /********************************************************************/
  187. GLOBALLOCK::~GLOBALLOCK( VOID )
  188. {
  189. #ifdef ENABLE_LOCK_STATISTICS
  190. //
  191. // Print the lock statistics.
  192. //
  193. DebugPrint
  194. (
  195. "Globallock : %d locks, %d timeouts.\n"
  196. TotalLocks,
  197. TotalTimeouts
  198. );
  199. #endif
  200. //
  201. // Close the semaphore handle.
  202. //
  203. if ( ! CloseHandle( Semaphore ) )
  204. { Failure( "Close semaphore in destructor for GLOBALLOCK" ); }
  205. //
  206. // Just to be tidy.
  207. //
  208. Semaphore = NULL;
  209. }