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.

231 lines
4.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: critsect.h
  7. //
  8. // Contents: critical section helper class
  9. //
  10. // Classes: CCriticalSection
  11. // CLockHandler
  12. // CLock
  13. //
  14. //
  15. // Notes:
  16. //
  17. // History: 13-Nov-97 rogerg Created.
  18. //
  19. //--------------------------------------------------------------------------
  20. #ifndef _CRITSECT_
  21. #define _CRITSECT_
  22. class CLock;
  23. class CCriticalSection
  24. {
  25. DWORD cRefs;
  26. CRITICAL_SECTION *m_pcsect;
  27. DWORD m_dwThreadID;
  28. public:
  29. inline CCriticalSection(CRITICAL_SECTION *pcsect,DWORD dwThreadID)
  30. {
  31. m_pcsect = pcsect;
  32. cRefs = 0;
  33. m_dwThreadID = dwThreadID;
  34. };
  35. inline ~CCriticalSection()
  36. {
  37. AssertSz(0 == cRefs,"UnReleased Critical Section");
  38. Assert(m_dwThreadID == GetCurrentThreadId());
  39. while(cRefs--) // unwind any left over cRefs
  40. {
  41. LeaveCriticalSection(m_pcsect);
  42. }
  43. };
  44. inline void Enter()
  45. {
  46. EnterCriticalSection(m_pcsect);
  47. Assert(m_dwThreadID == GetCurrentThreadId());
  48. ++cRefs;
  49. Assert(1 == cRefs); // we don't allow nested calls.
  50. };
  51. inline void Leave()
  52. {
  53. Assert(m_dwThreadID == GetCurrentThreadId());
  54. Assert(0 < cRefs);
  55. if (0 >= cRefs)
  56. return;
  57. --cRefs;
  58. Assert(0 == cRefs);
  59. LeaveCriticalSection(m_pcsect);
  60. };
  61. };
  62. class CLockHandler {
  63. public:
  64. CLockHandler();
  65. ~CLockHandler();
  66. void Lock(DWORD dwThreadId);
  67. void UnLock();
  68. inline DWORD GetLockThreadId() { return m_dwLockThreadId; };
  69. private:
  70. CRITICAL_SECTION m_CriticalSection; // critical section for the queue.
  71. DWORD m_dwLockThreadId; // thread that has the lock.
  72. friend CLock;
  73. };
  74. // helper class for making sure locks on the queue are released.
  75. class CLock
  76. {
  77. DWORD cRefs;
  78. CLockHandler *m_pLockHandler;
  79. DWORD m_dwThreadID;
  80. public:
  81. inline CLock(CLockHandler *pLockHandler)
  82. {
  83. m_pLockHandler = pLockHandler;
  84. cRefs = 0;
  85. m_dwThreadID = GetCurrentThreadId();
  86. };
  87. inline ~CLock()
  88. {
  89. AssertSz(0 == cRefs,"UnReleased Lock");
  90. Assert(m_dwThreadID == GetCurrentThreadId());
  91. while(cRefs--) // unwind any left over cRefs
  92. {
  93. m_pLockHandler->UnLock();
  94. }
  95. };
  96. inline void Enter()
  97. {
  98. Assert(m_dwThreadID == GetCurrentThreadId());
  99. ++cRefs;
  100. Assert(1 == cRefs); // we don't allow nested calls.
  101. m_pLockHandler->Lock(m_dwThreadID);
  102. };
  103. inline void Leave()
  104. {
  105. Assert(m_dwThreadID == GetCurrentThreadId());
  106. Assert(0 < cRefs);
  107. if (0 >= cRefs)
  108. return;
  109. --cRefs;
  110. Assert(0 == cRefs);
  111. m_pLockHandler->UnLock();
  112. };
  113. };
  114. #define ASSERT_LOCKHELD(pLockHandler) Assert(pLockHandler->GetLockThreadId() == GetCurrentThreadId());
  115. #define ASSERT_LOCKNOTHELD(pLockHandler) Assert(pLockHandler->GetLockThreadId() == 0);
  116. // helper class for Mutex locking
  117. class CMutex
  118. {
  119. HANDLE m_hMutex;
  120. BOOL m_fHasLock;
  121. BOOL m_fReleasedLock;
  122. public:
  123. inline CMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName)
  124. {
  125. m_hMutex = CreateMutex(lpMutexAttributes,bInitialOwner,lpName);
  126. // on failure routines go on just don't take the lock
  127. m_fHasLock = FALSE;
  128. m_fReleasedLock = FALSE;
  129. };
  130. inline ~CMutex()
  131. {
  132. AssertSz(!m_fHasLock,"UnReleased Mutex ");
  133. // if failed to release mutex release now.
  134. if (m_hMutex && m_fHasLock)
  135. {
  136. ReleaseMutex(m_hMutex);
  137. }
  138. if (m_hMutex)
  139. {
  140. CloseHandle(m_hMutex);
  141. }
  142. };
  143. inline void Enter(DWORD dwMilliseconds = INFINITE)
  144. {
  145. AssertSz(!m_fHasLock,"Tried to take Lock Twice");
  146. AssertSz(!m_fReleasedLock,"Tried to take lock After Released Mutex");
  147. if (!m_fHasLock && m_hMutex)
  148. {
  149. if (WAIT_OBJECT_0 ==WaitForSingleObject( m_hMutex, dwMilliseconds ))
  150. {
  151. m_fHasLock = TRUE;
  152. }
  153. }
  154. };
  155. inline void Leave()
  156. {
  157. Assert(m_fHasLock);
  158. if (m_fHasLock && m_hMutex)
  159. {
  160. ReleaseMutex(m_hMutex);
  161. }
  162. if (m_hMutex)
  163. {
  164. CloseHandle(m_hMutex);
  165. }
  166. m_hMutex = NULL;
  167. m_fHasLock = FALSE;
  168. m_fReleasedLock = TRUE;
  169. };
  170. };
  171. #endif // _CRITSECT_