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.

146 lines
2.9 KiB

  1. //==========================================================================
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright 1998 - 1999 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------
  11. #ifndef _CRITSECT_
  12. #define _CRITSECT_
  13. class CLock;
  14. class CCriticalSection
  15. {
  16. DWORD cRefs;
  17. CRITICAL_SECTION *m_pcsect;
  18. DWORD m_dwThreadID;
  19. public:
  20. inline CCriticalSection(CRITICAL_SECTION *pcsect,DWORD dwThreadID)
  21. {
  22. m_pcsect = pcsect;
  23. cRefs = 0;
  24. m_dwThreadID = dwThreadID;
  25. };
  26. inline ~CCriticalSection()
  27. {
  28. AssertSz(0 == cRefs,"UnReleased Critical Section");
  29. Assert(m_dwThreadID == GetCurrentThreadId());
  30. while(cRefs--) // unwind any left over cRefs
  31. {
  32. LeaveCriticalSection(m_pcsect);
  33. }
  34. };
  35. inline void Enter()
  36. {
  37. EnterCriticalSection(m_pcsect);
  38. Assert(m_dwThreadID == GetCurrentThreadId());
  39. ++cRefs;
  40. Assert(1 == cRefs); // we don't allow nested calls.
  41. };
  42. inline void Leave()
  43. {
  44. Assert(m_dwThreadID == GetCurrentThreadId());
  45. Assert(0 < cRefs);
  46. if (0 >= cRefs)
  47. return;
  48. --cRefs;
  49. Assert(0 == cRefs);
  50. LeaveCriticalSection(m_pcsect);
  51. };
  52. };
  53. class CLockHandler {
  54. public:
  55. CLockHandler();
  56. ~CLockHandler();
  57. void Lock(DWORD dwThreadId);
  58. void UnLock();
  59. inline DWORD GetLockThreadId() { return m_dwLockThreadId; };
  60. private:
  61. CRITICAL_SECTION m_CriticalSection; // critical section for the queue.
  62. DWORD m_dwLockThreadId; // thread that has the lock.
  63. friend CLock;
  64. };
  65. // helper class for making sure locks on the queue are released.
  66. class CLock
  67. {
  68. DWORD cRefs;
  69. CLockHandler *m_pLockHandler;
  70. DWORD m_dwThreadID;
  71. public:
  72. inline CLock(CLockHandler *pLockHandler)
  73. {
  74. m_pLockHandler = pLockHandler;
  75. cRefs = 0;
  76. m_dwThreadID = GetCurrentThreadId();
  77. };
  78. inline ~CLock()
  79. {
  80. AssertSz(0 == cRefs,"UnReleased Lock");
  81. Assert(m_dwThreadID == GetCurrentThreadId());
  82. while(cRefs--) // unwind any left over cRefs
  83. {
  84. m_pLockHandler->UnLock();
  85. }
  86. };
  87. inline void Enter()
  88. {
  89. Assert(m_dwThreadID == GetCurrentThreadId());
  90. ++cRefs;
  91. Assert(1 == cRefs); // we don't allow nested calls.
  92. m_pLockHandler->Lock(m_dwThreadID);
  93. };
  94. inline void Leave()
  95. {
  96. Assert(m_dwThreadID == GetCurrentThreadId());
  97. Assert(0 < cRefs);
  98. if (0 >= cRefs)
  99. return;
  100. --cRefs;
  101. Assert(0 == cRefs);
  102. m_pLockHandler->UnLock();
  103. };
  104. };
  105. #define ASSERT_LOCKHELD(pLockHandler) Assert(pLockHandler->GetLockThreadId() == GetCurrentThreadId());
  106. #define ASSERT_LOCKNOTHELD(pLockHandler) Assert(pLockHandler->GetLockThreadId() == 0);
  107. #endif // _CRITSECT_