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.

125 lines
3.2 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Lock.cpp
  4. //
  5. // Copyright (C) 1998, 1999 Microsoft Corporation. All rights reserved.
  6. //
  7. // Abstract :
  8. //
  9. // This is the implementation of the CLock class. This class was created in order to
  10. // support automatic destruction of C++ object when an exception is thrown.
  11. //
  12. // Note :
  13. //
  14. // The CLock class is not thread safe (although the CCriticalSection class is). The CLock
  15. // class should be used as a local variable when locking using a CCriticalSection object.
  16. // This is done in order to warranty that all locks on an object are released when an
  17. // exception is thrown.
  18. //
  19. // History :
  20. //
  21. // 05/06/1999 luish Created
  22. //
  23. //////////////////////////////////////////////////////////////////////////////////////////////
  24. #include <assert.h>
  25. #include "Lock.h"
  26. #include "ExceptionHandler.h"
  27. #include "AppManDebug.h"
  28. //To flag as DBG_LOCK
  29. #ifdef DBG_MODULE
  30. #undef DBG_MODULE
  31. #endif
  32. #define DBG_MODULE DBG_LOCK
  33. //////////////////////////////////////////////////////////////////////////////////////////////
  34. //
  35. //////////////////////////////////////////////////////////////////////////////////////////////
  36. CLock::CLock(CCriticalSection * lpCriticalSection)
  37. {
  38. FUNCTION("CLock::CLock (CCriticalSection * lpCriticalSection)");
  39. assert(NULL != lpCriticalSection);
  40. //
  41. // We need to record what the lock could of the critical section when the CLock object
  42. // is created. When the object is destroyed we make sure that the lock count
  43. // on the critical section object is the same as when CLock was created
  44. //
  45. m_lpCriticalSection = lpCriticalSection;
  46. m_dwBaseLockCount = m_lpCriticalSection->GetLockCount();
  47. m_dwLockCount = 0;
  48. }
  49. //////////////////////////////////////////////////////////////////////////////////////////////
  50. //
  51. //////////////////////////////////////////////////////////////////////////////////////////////
  52. CLock::~CLock(void)
  53. {
  54. FUNCTION("CLock::~CLock (void)");
  55. DWORD dwLockCount;
  56. do
  57. {
  58. dwLockCount = m_lpCriticalSection->GetLockCount();
  59. //
  60. // If the lock count on the critical section is greater than when the CLock object was
  61. // created, then we call m_lpCriticalSection->Leave()
  62. //
  63. if (dwLockCount > m_dwBaseLockCount)
  64. {
  65. m_lpCriticalSection->Leave();
  66. }
  67. }
  68. while (dwLockCount > m_dwBaseLockCount);
  69. }
  70. //////////////////////////////////////////////////////////////////////////////////////////////
  71. //
  72. //////////////////////////////////////////////////////////////////////////////////////////////
  73. STDMETHODIMP CLock::Lock(void)
  74. {
  75. FUNCTION("CLock::Lock ()");
  76. m_lpCriticalSection->Enter();
  77. m_dwLockCount++;
  78. return S_OK;
  79. }
  80. //////////////////////////////////////////////////////////////////////////////////////////////
  81. //
  82. //////////////////////////////////////////////////////////////////////////////////////////////
  83. STDMETHODIMP CLock::UnLock(void)
  84. {
  85. FUNCTION("CLock::UnLock ()");
  86. HRESULT hResult;
  87. if (0 < m_dwLockCount)
  88. {
  89. hResult = m_lpCriticalSection->Leave();
  90. //
  91. // Make sure that hResult == S_OK and not S_FALSE
  92. //
  93. if (S_OK == hResult)
  94. {
  95. m_dwLockCount--;
  96. }
  97. return S_OK;
  98. }
  99. return S_FALSE;
  100. }