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.

197 lines
4.7 KiB

  1. /*****************************************************************/
  2. /** Microsoft Windows for Workgroups **/
  3. /** Copyright (C) Microsoft Corp., 1991-1992 **/
  4. /*****************************************************************/
  5. /* NPCRIT.H -- Definition of CRITSEC classes.
  6. *
  7. * History:
  8. * gregj 11/01/93 Created
  9. * lens 02/25/94 Modified to use CRITICAL_SECTIONs Reinitialize().
  10. * Took out spin-loop interlock.
  11. */
  12. #ifndef _INC_CRITSEC
  13. #define _INC_CRITSEC
  14. #ifndef RC_INVOKED
  15. #pragma pack(1)
  16. #endif
  17. extern "C"
  18. {
  19. /* extern DECLSPEC_IMPORT
  20. VOID
  21. WINAPI
  22. ReinitializeCriticalSection(LPCRITICAL_SECTION lpcs); - in windefs.h */
  23. extern DECLSPEC_IMPORT
  24. VOID
  25. WINAPI
  26. UninitializeCriticalSection(LPCRITICAL_SECTION lpcs);
  27. // codework: remove following and make MEMWATCH use critical sections.
  28. #ifdef DEBUG
  29. void WaitForInterlock(volatile BYTE *pByte);
  30. void ReleaseInterlock(volatile BYTE *pByte);
  31. #endif /* DEBUG */
  32. }
  33. /*************************************************************************
  34. NAME: CRITSEC
  35. SYNOPSIS: Class wrapper for global critical section
  36. INTERFACE: Init(pszName)
  37. Initializes the critical section.
  38. Term()
  39. Cleans up the critical section.
  40. PRIVATE: Enter()
  41. Enter the critical section, waiting for others
  42. to leave if necessary.
  43. Leave()
  44. Leave the critical section, unblocking other waiters.
  45. PARENT: None
  46. USES: None
  47. CAVEATS: This class is not initialized with its constructor because
  48. it should be instantiated at global scope, which introduces
  49. constructor-linker problems. Instead, its fields should be
  50. initialized to all zeroes, and Init() should be called at
  51. process attach time. Term() should be called at process
  52. detach.
  53. NOTES: The class's initialization takes care of synchronizing
  54. itself to protect against multiple simultaneous inits.
  55. HISTORY:
  56. 11/01/93 gregj Created
  57. 02/25/94 lens Modified to use CRITICAL_SECTION directly.
  58. **************************************************************************/
  59. class CRITSEC
  60. {
  61. friend class TAKE_CRITSEC;
  62. private:
  63. CRITICAL_SECTION _critsec;
  64. public:
  65. void Enter() { ::EnterCriticalSection(&_critsec); }
  66. void Leave() { ::LeaveCriticalSection(&_critsec); }
  67. #ifndef WINNT
  68. void Init() { ::ReinitializeCriticalSection(&_critsec); }
  69. void Term() { /* codework: add ::UninitializeCriticalSection(&_critsec); */}
  70. #endif /* WINNT */
  71. };
  72. /*************************************************************************
  73. NAME: TAKE_CRITSEC
  74. SYNOPSIS: Class wrapper to take a critical section.
  75. INTERFACE: TAKE_CRITSEC(critsec)
  76. Construct with the global CRITICAL_SECTION object to take.
  77. ~TAKE_CRITSEC()
  78. Destructor automatically releases the critical section.
  79. Release()
  80. Releases the critical section manually.
  81. Take()
  82. Takes the critical section manually.
  83. PARENT: None
  84. USES: None
  85. CAVEATS: None
  86. NOTES: Instantiate one of these classes in a block of code
  87. when you want that block of code to be protected
  88. against re-entrancy.
  89. The Take() and Release() functions should rarely be necessary,
  90. and must be used in matched pairs with Release() called first.
  91. HISTORY:
  92. 11/01/93 gregj Created
  93. **************************************************************************/
  94. class TAKE_CRITSEC
  95. {
  96. private:
  97. CRITSEC & const _critsec;
  98. public:
  99. void Take(void) { _critsec.Enter(); }
  100. void Release(void) { _critsec.Leave(); }
  101. TAKE_CRITSEC(CRITSEC& critsec) : _critsec(critsec) { Take(); }
  102. ~TAKE_CRITSEC() { Release(); }
  103. };
  104. /*************************************************************************
  105. NAME: TAKE_MUTEX
  106. SYNOPSIS: Class wrapper to take a mutex.
  107. INTERFACE: TAKE_MUTEX(hMutex)
  108. Construct with the mutex handle to take.
  109. ~TAKE_MUTEX()
  110. Destructor automatically releases the mutex.
  111. Release()
  112. Releases the mutex manually.
  113. Take()
  114. Takes the mutex manually.
  115. PARENT: None
  116. USES: None
  117. CAVEATS: None
  118. NOTES: Instantiate one of these classes in a block of code
  119. when you want that block of code to be protected
  120. against re-entrancy.
  121. The Take() and Release() functions should rarely be necessary,
  122. and must be used in matched pairs with Release() called first.
  123. HISTORY:
  124. 09/27/94 lens Created
  125. **************************************************************************/
  126. class TAKE_MUTEX
  127. {
  128. private:
  129. HANDLE const _hMutex;
  130. public:
  131. void Take(void) { WaitForSingleObject(_hMutex, INFINITE); }
  132. void Release(void) { ReleaseMutex(_hMutex); }
  133. TAKE_MUTEX(HANDLE hMutex) : _hMutex(hMutex) { Take(); }
  134. ~TAKE_MUTEX() { Release(); }
  135. };
  136. #ifndef RC_INVOKED
  137. #pragma pack()
  138. #endif
  139. #endif /* _INC_BUFFER */