windows-nt/Source/XPSP1/NT/net/rras/cm/common/source/mutex.cpp
2020-09-26 16:20:57 +08:00

158 lines
4.2 KiB
C++

//+----------------------------------------------------------------------------
//
// File: mutex.cpp
//
// Module: Common Code
//
// Synopsis: Implementation of the class CNamedMutex
//
// Copyright (c) 1998-1999 Microsoft Corporation
//
// Author: fengsun Created 02/26/98
//
//+----------------------------------------------------------------------------
//+----------------------------------------------------------------------------
//
// Function: CNamedMutex::Lock
//
// Synopsis:
//
// Arguments: LPCTSTR lpName - Name of the mutex
// BOOL fWait - Whether caller want to wait, if mutex is not available
// Default is FALSE
// DWORD dwMilliseconds - Timeout for wait, default is INFINITE
// BOOL fNoAbandon - Don't acquire an abandoned mutex
//
// Returns: BOOL - Whether the mutex is acquired, if TRUE, caller should call
// Unlock to release the lock. Otherwise, the lock will be
// released in destructor
//
// History: fengsun Created Header 02/26/98
// nickball Added fNoAbandon 03/32/99
//
//+----------------------------------------------------------------------------
BOOL CNamedMutex::Lock(LPCTSTR lpName, BOOL fWait, DWORD dwMilliseconds, BOOL fNoAbandon)
{
MYDBGASSERT(m_hMutex == NULL);
MYDBGASSERT(lpName);
m_fOwn = FALSE;
CMTRACE1(TEXT("CNamedMutex::Lock() - Attempting to acquire mutex - %s"), lpName);
m_hMutex = CreateMutexU(NULL,TRUE,lpName);
MYDBGASSERT(m_hMutex);
if (m_hMutex == NULL)
{
return FALSE;
}
DWORD dwRet = GetLastError();
if (dwRet != ERROR_ALREADY_EXISTS)
{
//
// We got the mutex
//
m_fOwn = TRUE;
return TRUE;
}
CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex already exists - %s"), lpName);
//
// Someone else own the mutex
//
if (!fWait) // caller does not want to wait
{
CMTRACE1(TEXT("CNamedMutex::Lock() - Not waiting for mutex - %s"), lpName);
CloseHandle(m_hMutex);
m_hMutex = NULL;
return FALSE;
}
//
// Caller want to wait until the mutex is released
//
CMTRACE(TEXT("CNamedMutex::Lock() - Entering Mutex wait"));
dwRet = WaitForSingleObject(m_hMutex, dwMilliseconds);
switch (dwRet)
{
case WAIT_ABANDONED:
CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex was abandoned by previous owner - %s"), lpName);
//
// If the thread that owns a mutex is blown away, the wait will
// release with a return of WAIT_ABANDON. This typically happens
// if the thread is dumped from memory, or someone doesn't clean
// up before terminating. Either way, the caller may not want to
// acquire an abandoned mutex, so just release it if that is what
// the caller specified and the wait returned.
//
if (fNoAbandon)
{
CMTRACE1(TEXT("CNamedMutex::Lock() - Releasing abandoned mutex- %s"), lpName);
ReleaseMutex(m_hMutex);
break;
}
//
// Fall through to standard mutex acquisition
//
case WAIT_OBJECT_0:
//
// We get the mutex
//
m_fOwn = TRUE;
CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex acquired - %s"), lpName);
return TRUE;
default:
CMTRACE1(TEXT("CNamedMutex::Lock() - Mutex wait timed out - %s"), lpName);
break;
}
CloseHandle(m_hMutex);
m_hMutex = NULL;
return FALSE;
}
//+----------------------------------------------------------------------------
//
// Function: CNamedMutex::Unlock
//
// Synopsis: Release the mutex
//
// Arguments:
//
// Returns: NONE
//
// History: fengsun Created Header 2/19/98
//
//+----------------------------------------------------------------------------
void CNamedMutex::Unlock()
{
if (m_hMutex != NULL)
{
if (m_fOwn)
{
ReleaseMutex(m_hMutex);
m_fOwn = FALSE;
}
CloseHandle(m_hMutex);
m_hMutex = NULL;
}
}