Source code of Windows XP (NT5)
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.

139 lines
3.7 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: SIMCRIT.H
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/6/1999
  12. *
  13. * DESCRIPTION: Simple critical section implementation. Note the hideous hack
  14. * to get around the fact that many of our components don't use the CRT (so global
  15. * and static classes don't have their constructors called. Ever.
  16. * The solution is to link to MSVCRT.LIB and set _DllMainCRTStartup as the entry
  17. * point in your DLL, instead of DllMain. The way this is coded is not thread safe.
  18. * Two threads could call InitializeCriticalSection at the same time. If you setup
  19. * your build as discussed above, this won't be a problem. Note that this hack only
  20. * affects the use of this class when you have a GLOBAL or STATIC instance of a
  21. * critical section.
  22. *
  23. *******************************************************************************/
  24. #ifndef __SIMCRIT_H_INCLUDED
  25. #define __SIMCRIT_H_INCLUDED
  26. #include <windows.h>
  27. class CSimpleCriticalSection
  28. {
  29. private:
  30. CRITICAL_SECTION m_CriticalSection;
  31. bool m_bInitCalled;
  32. private:
  33. //
  34. // No implementation
  35. //
  36. CSimpleCriticalSection( const CSimpleCriticalSection & );
  37. CSimpleCriticalSection &operator=( const CSimpleCriticalSection & );
  38. public:
  39. CSimpleCriticalSection(void)
  40. : m_bInitCalled(false)
  41. {
  42. Initialize();
  43. }
  44. ~CSimpleCriticalSection(void)
  45. {
  46. if (m_bInitCalled)
  47. {
  48. DeleteCriticalSection(&m_CriticalSection);
  49. }
  50. }
  51. void Initialize(void)
  52. {
  53. if (!m_bInitCalled)
  54. {
  55. _try
  56. {
  57. InitializeCriticalSection(&m_CriticalSection);
  58. m_bInitCalled = true;
  59. }
  60. _except(EXCEPTION_EXECUTE_HANDLER)
  61. {
  62. #if defined(DBG)
  63. OutputDebugString(TEXT("CSimpleCriticalSection::Initialize(), InitializeCriticalSection failed\n"));
  64. DebugBreak();
  65. #endif
  66. m_bInitCalled = false;
  67. }
  68. }
  69. }
  70. void Enter(void)
  71. {
  72. if (!m_bInitCalled)
  73. {
  74. Initialize();
  75. }
  76. if (m_bInitCalled)
  77. {
  78. EnterCriticalSection(&m_CriticalSection);
  79. }
  80. }
  81. void Leave(void)
  82. {
  83. if (m_bInitCalled)
  84. {
  85. LeaveCriticalSection(&m_CriticalSection);
  86. }
  87. }
  88. CRITICAL_SECTION &cs(void)
  89. {
  90. return m_CriticalSection;
  91. }
  92. };
  93. class CAutoCriticalSection
  94. {
  95. private:
  96. PVOID m_pvCriticalSection;
  97. bool m_bUsingPlainCriticalSection;
  98. private:
  99. // No implementation
  100. CAutoCriticalSection(void);
  101. CAutoCriticalSection( const CAutoCriticalSection & );
  102. CAutoCriticalSection &operator=( const CAutoCriticalSection & );
  103. public:
  104. CAutoCriticalSection( CSimpleCriticalSection &criticalSection )
  105. : m_pvCriticalSection(&criticalSection),
  106. m_bUsingPlainCriticalSection(false)
  107. {
  108. reinterpret_cast<CSimpleCriticalSection*>(m_pvCriticalSection)->Enter();
  109. }
  110. CAutoCriticalSection( CRITICAL_SECTION &criticalSection )
  111. : m_pvCriticalSection(&criticalSection),
  112. m_bUsingPlainCriticalSection(true)
  113. {
  114. EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(m_pvCriticalSection));
  115. }
  116. ~CAutoCriticalSection(void)
  117. {
  118. if (m_bUsingPlainCriticalSection)
  119. {
  120. LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(m_pvCriticalSection));
  121. }
  122. else
  123. {
  124. reinterpret_cast<CSimpleCriticalSection*>(m_pvCriticalSection)->Leave();
  125. }
  126. m_pvCriticalSection = NULL;
  127. }
  128. };
  129. #endif //__SIMCRIT_H_INCLUDED