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.

157 lines
4.2 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: mutex.cpp
  4. //
  5. // Module: Common Code
  6. //
  7. // Synopsis: Implementation of the class CNamedMutex
  8. //
  9. // Copyright (c) 1998-1999 Microsoft Corporation
  10. //
  11. // Author: fengsun Created 02/26/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. //+----------------------------------------------------------------------------
  15. //
  16. // Function: CNamedMutex::Lock
  17. //
  18. // Synopsis:
  19. //
  20. // Arguments: LPCTSTR lpName - Name of the mutex
  21. // BOOL fWait - Whether caller want to wait, if mutex is not available
  22. // Default is FALSE
  23. // DWORD dwMilliseconds - Timeout for wait, default is INFINITE
  24. // BOOL fNoAbandon - Don't acquire an abandoned mutex
  25. //
  26. // Returns: BOOL - Whether the mutex is acquired, if TRUE, caller should call
  27. // Unlock to release the lock. Otherwise, the lock will be
  28. // released in destructor
  29. //
  30. // History: fengsun Created Header 02/26/98
  31. // nickball Added fNoAbandon 03/32/99
  32. //
  33. //+----------------------------------------------------------------------------
  34. BOOL CNamedMutex::Lock(LPCTSTR lpName, BOOL fWait, DWORD dwMilliseconds, BOOL fNoAbandon)
  35. {
  36. MYDBGASSERT(m_hMutex == NULL);
  37. MYDBGASSERT(lpName);
  38. m_fOwn = FALSE;
  39. CMTRACE1(TEXT("CNamedMutex::Lock() - Attempting to acquire mutex - %s"), lpName);
  40. m_hMutex = CreateMutexU(NULL,TRUE,lpName);
  41. MYDBGASSERT(m_hMutex);
  42. if (m_hMutex == NULL)
  43. {
  44. return FALSE;
  45. }
  46. DWORD dwRet = GetLastError();
  47. if (dwRet != ERROR_ALREADY_EXISTS)
  48. {
  49. //
  50. // We got the mutex
  51. //
  52. m_fOwn = TRUE;
  53. return TRUE;
  54. }
  55. CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex already exists - %s"), lpName);
  56. //
  57. // Someone else own the mutex
  58. //
  59. if (!fWait) // caller does not want to wait
  60. {
  61. CMTRACE1(TEXT("CNamedMutex::Lock() - Not waiting for mutex - %s"), lpName);
  62. CloseHandle(m_hMutex);
  63. m_hMutex = NULL;
  64. return FALSE;
  65. }
  66. //
  67. // Caller want to wait until the mutex is released
  68. //
  69. CMTRACE(TEXT("CNamedMutex::Lock() - Entering Mutex wait"));
  70. dwRet = WaitForSingleObject(m_hMutex, dwMilliseconds);
  71. switch (dwRet)
  72. {
  73. case WAIT_ABANDONED:
  74. CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex was abandoned by previous owner - %s"), lpName);
  75. //
  76. // If the thread that owns a mutex is blown away, the wait will
  77. // release with a return of WAIT_ABANDON. This typically happens
  78. // if the thread is dumped from memory, or someone doesn't clean
  79. // up before terminating. Either way, the caller may not want to
  80. // acquire an abandoned mutex, so just release it if that is what
  81. // the caller specified and the wait returned.
  82. //
  83. if (fNoAbandon)
  84. {
  85. CMTRACE1(TEXT("CNamedMutex::Lock() - Releasing abandoned mutex- %s"), lpName);
  86. ReleaseMutex(m_hMutex);
  87. break;
  88. }
  89. //
  90. // Fall through to standard mutex acquisition
  91. //
  92. case WAIT_OBJECT_0:
  93. //
  94. // We get the mutex
  95. //
  96. m_fOwn = TRUE;
  97. CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex acquired - %s"), lpName);
  98. return TRUE;
  99. default:
  100. CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex wait timed out - %s"), lpName);
  101. break;
  102. }
  103. CloseHandle(m_hMutex);
  104. m_hMutex = NULL;
  105. return FALSE;
  106. }
  107. //+----------------------------------------------------------------------------
  108. //
  109. // Function: CNamedMutex::Unlock
  110. //
  111. // Synopsis: Release the mutex
  112. //
  113. // Arguments:
  114. //
  115. // Returns: NONE
  116. //
  117. // History: fengsun Created Header 2/19/98
  118. //
  119. //+----------------------------------------------------------------------------
  120. void CNamedMutex::Unlock()
  121. {
  122. if (m_hMutex != NULL)
  123. {
  124. if (m_fOwn)
  125. {
  126. ReleaseMutex(m_hMutex);
  127. m_fOwn = FALSE;
  128. }
  129. CloseHandle(m_hMutex);
  130. m_hMutex = NULL;
  131. }
  132. }