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.

215 lines
3.6 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. crtsect.cxx
  6. Abstract:
  7. Critical Section class
  8. Author:
  9. Steve Kiraly (SteveKi) 30-Mar-1997
  10. Mark Lawrence (mlawrenc) 08-Mar-2000
  11. Revision History:
  12. Moved Over from debug library and changed name. Note that
  13. the funny const_casts all over the place are to allow the
  14. methods to be exported as const. This is necessary in a class
  15. exports a const method that does not want to allow other methods to
  16. run. This is legitimate and it is cleaner to do this in one place
  17. (i.e. here)
  18. --*/
  19. #include "spllibp.hxx"
  20. #include "CSRutility.hxx"
  21. #include "CSRcrtsect.hxx"
  22. namespace NCoreLibrary
  23. {
  24. TCriticalSection::
  25. TCriticalSection(
  26. IN BOOL bPrealloc
  27. ) : m_hr(E_FAIL),
  28. m_dwOwnerId(0),
  29. m_uEnterCount(0)
  30. {
  31. m_hr = Initialize(bPrealloc);
  32. }
  33. TCriticalSection::
  34. ~TCriticalSection(
  35. VOID
  36. )
  37. {
  38. Release();
  39. }
  40. HRESULT
  41. TCriticalSection::
  42. IsValid(
  43. VOID
  44. ) const
  45. {
  46. return m_hr;
  47. }
  48. HRESULT
  49. TCriticalSection::
  50. Enter(
  51. VOID
  52. ) const
  53. {
  54. //
  55. // Since EnterCriticalSection cannot fail or throw an exception we just
  56. // return S_OK
  57. //
  58. EnterCriticalSection(const_cast<LPCRITICAL_SECTION>(&m_CriticalSection));
  59. const_cast<UINT &>(m_uEnterCount)++;
  60. const_cast<DWORD &>(m_dwOwnerId) = GetCurrentThreadId();
  61. return S_OK;
  62. }
  63. HRESULT
  64. TCriticalSection::
  65. Leave(
  66. VOID
  67. ) const
  68. {
  69. const_cast<UINT &>(m_uEnterCount)--;
  70. if (m_uEnterCount == 0)
  71. {
  72. const_cast<DWORD &>(m_dwOwnerId) = 0;
  73. }
  74. LeaveCriticalSection(const_cast<LPCRITICAL_SECTION>(&m_CriticalSection));
  75. return S_OK;
  76. }
  77. HRESULT
  78. TCriticalSection::
  79. GetOwningThreadId(
  80. OUT DWORD *pdwThreadId
  81. )
  82. {
  83. HRESULT hRetval = pdwThreadId ? S_OK : E_INVALIDARG;
  84. if (SUCCEEDED(hRetval))
  85. {
  86. *pdwThreadId = m_dwOwnerId;
  87. }
  88. return hRetval;
  89. }
  90. VOID
  91. TCriticalSection::
  92. CheckInCS(
  93. VOID
  94. ) const
  95. {
  96. DWORD dwCurrentId = GetCurrentThreadId();
  97. }
  98. VOID
  99. TCriticalSection::
  100. CheckOutOfCS(
  101. VOID
  102. ) const
  103. {
  104. DWORD dwCurrentId = GetCurrentThreadId();
  105. }
  106. HRESULT
  107. TCriticalSection::
  108. Initialize(
  109. BOOL bPrealloc
  110. )
  111. {
  112. HRESULT hRetval = E_FAIL;
  113. m_uEnterCount = 0;
  114. m_dwOwnerId = 0;
  115. //
  116. // If the high order bit is set in InitializeCriticalSectionAndSpin
  117. // count, then the Event used internally will be allocated up front.
  118. // Then, Enter() is guaranteed not to throw an exception.
  119. //
  120. hRetval = InitializeCriticalSectionAndSpinCount(&m_CriticalSection, ((bPrealloc ? 1 : 0) << (sizeof(DWORD) * 8 - 1))) ? S_OK : GetLastErrorAsHResult();
  121. return hRetval;
  122. }
  123. VOID
  124. TCriticalSection::
  125. Release(
  126. VOID
  127. )
  128. {
  129. if (SUCCEEDED(m_hr))
  130. {
  131. DeleteCriticalSection(&m_CriticalSection);
  132. m_hr = E_FAIL;
  133. }
  134. }
  135. TCriticalSection::TLock::
  136. TLock(
  137. const TCriticalSection &CriticalSection
  138. ) : m_CriticalSection(CriticalSection)
  139. {
  140. m_hr = m_CriticalSection.Enter();
  141. }
  142. TCriticalSection::TLock::
  143. ~TLock(
  144. VOID
  145. )
  146. {
  147. if (SUCCEEDED(m_hr))
  148. {
  149. m_CriticalSection.Leave();
  150. }
  151. }
  152. TCriticalSection::TUnLock::
  153. TUnLock(
  154. const TCriticalSection &CriticalSection
  155. ) : m_CriticalSection(CriticalSection)
  156. {
  157. m_hr = m_CriticalSection.Leave();
  158. }
  159. TCriticalSection::TUnLock::
  160. ~TUnLock(
  161. VOID
  162. )
  163. {
  164. if (SUCCEEDED(m_hr))
  165. {
  166. m_CriticalSection.Enter();
  167. }
  168. }
  169. } // namespace ncorlibrary