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.
499 lines
9.6 KiB
499 lines
9.6 KiB
//
|
|
// cicmutex.h
|
|
//
|
|
|
|
|
|
#ifndef CICMUTEX_H
|
|
#define CICMUTEX_H
|
|
|
|
|
|
class CCicMutexHelper;
|
|
|
|
struct CCicMutex
|
|
{
|
|
public:
|
|
BOOL Init(SECURITY_ATTRIBUTES *psa, TCHAR *psz)
|
|
{
|
|
_hMutex = CreateMutex(psa, FALSE, psz);
|
|
Assert(_hMutex);
|
|
return _hMutex ? TRUE : FALSE;
|
|
}
|
|
|
|
void Uninit()
|
|
{
|
|
if (_hMutex)
|
|
CloseHandle(_hMutex);
|
|
_hMutex = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL Enter()
|
|
{
|
|
Assert(_hMutex);
|
|
DWORD dwWaitResult = WaitForSingleObject(_hMutex, 5000);
|
|
if (dwWaitResult == WAIT_OBJECT_0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else if (dwWaitResult == WAIT_ABANDONED)
|
|
{
|
|
TraceMsg(TF_EVENT, "CicMutex abandoned");
|
|
return TRUE;
|
|
}
|
|
|
|
TraceMsg(TF_EVENT, "CicMutex Time Out");
|
|
|
|
//
|
|
// assert here to debug stop.
|
|
//
|
|
Assert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
void Leave()
|
|
{
|
|
Assert(_hMutex);
|
|
ReleaseMutex(_hMutex);
|
|
}
|
|
|
|
private:
|
|
HANDLE _hMutex;
|
|
};
|
|
|
|
class CCicMutexHelperStatic
|
|
{
|
|
public:
|
|
void Init(CCicMutex *pcicmutex)
|
|
{
|
|
_pcicmutex = pcicmutex;
|
|
SetIn(FALSE);
|
|
}
|
|
|
|
void Uninit()
|
|
{
|
|
Assert(!_fIn);
|
|
_pcicmutex = NULL;
|
|
}
|
|
|
|
BOOL Enter()
|
|
{
|
|
BOOL bRet = _pcicmutex->Enter();
|
|
SetIn(TRUE);
|
|
return bRet;
|
|
}
|
|
|
|
void Leave()
|
|
{
|
|
SetIn(FALSE);
|
|
_pcicmutex->Leave();
|
|
}
|
|
|
|
BOOL Invalid()
|
|
{
|
|
return _pcicmutex ? TRUE : FALSE;
|
|
}
|
|
|
|
protected:
|
|
CCicMutex *_pcicmutex;
|
|
#ifdef DEBUG
|
|
void SetIn(BOOL fIn) {_fIn = fIn;}
|
|
BOOL _fIn;
|
|
#else
|
|
void SetIn(BOOL fIn) {}
|
|
#endif
|
|
};
|
|
|
|
class CCicMutexHelper : public CCicMutexHelperStatic
|
|
{
|
|
public:
|
|
CCicMutexHelper(CCicMutex *pcicmutex = NULL)
|
|
{
|
|
#ifdef DEBUG
|
|
_fIn = FALSE;
|
|
#endif
|
|
_pcicmutex = NULL;
|
|
if (pcicmutex)
|
|
Init(pcicmutex);
|
|
}
|
|
|
|
~CCicMutexHelper()
|
|
{
|
|
Assert(!_fIn);
|
|
}
|
|
};
|
|
|
|
class CCicFileMappingStatic
|
|
{
|
|
public:
|
|
void BaseInit()
|
|
{
|
|
_pv = NULL;
|
|
_hfm = NULL;
|
|
}
|
|
|
|
void Finalize()
|
|
{
|
|
if (_fUseMutex)
|
|
{
|
|
Close();
|
|
|
|
//
|
|
// mutexhlp could be invalid if Uninit() was called.
|
|
//
|
|
if (_mutexhlp.Invalid())
|
|
_mutexhlp.Leave();
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Close() must be called when client's own mutex is released,
|
|
// if _fuseMutex is FALSE.
|
|
//
|
|
Assert(!_hfm);
|
|
}
|
|
}
|
|
|
|
void Init(TCHAR *pszFile, CCicMutex *pmutex)
|
|
{
|
|
Assert(!_hfm);
|
|
Assert(!_pv);
|
|
if (pmutex)
|
|
_mutexhlp.Init(pmutex);
|
|
|
|
_pszFile = pszFile;
|
|
_fCreated = FALSE;
|
|
_fUseMutex = pmutex ? TRUE : FALSE;
|
|
}
|
|
|
|
void Uninit()
|
|
{
|
|
_mutexhlp.Uninit();
|
|
}
|
|
|
|
void *Open()
|
|
{
|
|
Assert(!_hfm);
|
|
|
|
if (!_pszFile)
|
|
{
|
|
Assert(0);
|
|
return NULL;
|
|
}
|
|
|
|
_hfm = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, _pszFile);
|
|
|
|
if (_hfm == NULL)
|
|
return NULL;
|
|
|
|
return _Map();
|
|
}
|
|
|
|
void *Create(SECURITY_ATTRIBUTES *psa, ULONG cbSize, BOOL *pfAlreadyExists)
|
|
{
|
|
Assert(!_hfm);
|
|
|
|
if (!_pszFile)
|
|
{
|
|
Assert(0);
|
|
return NULL;
|
|
}
|
|
|
|
_hfm = CreateFileMapping(INVALID_HANDLE_VALUE, psa, PAGE_READWRITE,
|
|
0, cbSize, _pszFile);
|
|
|
|
if (pfAlreadyExists != NULL)
|
|
{
|
|
*pfAlreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);
|
|
}
|
|
|
|
if (_hfm == NULL)
|
|
return NULL;
|
|
|
|
_fCreated = TRUE;
|
|
return _Map();
|
|
}
|
|
|
|
BOOL Flush(UINT cbSize)
|
|
{
|
|
if (!_pv)
|
|
return FALSE;
|
|
|
|
return FlushViewOfFile(_pv, cbSize);
|
|
}
|
|
|
|
void Close()
|
|
{
|
|
if (_pv)
|
|
UnmapViewOfFile(_pv);
|
|
|
|
if (_hfm)
|
|
CloseHandle(_hfm);
|
|
|
|
_pv = NULL;
|
|
_hfm = NULL;
|
|
_fCreated = FALSE;
|
|
}
|
|
|
|
void SetName(TCHAR *psz) {_pszFile = psz;}
|
|
|
|
BOOL Enter()
|
|
{
|
|
if (_fUseMutex)
|
|
if (!_mutexhlp.Enter())
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void Leave()
|
|
{
|
|
if (_fUseMutex)
|
|
_mutexhlp.Leave();
|
|
}
|
|
|
|
BOOL IsCreated() { return _fCreated; }
|
|
|
|
private:
|
|
void *_Map()
|
|
{
|
|
Assert(!_pv);
|
|
_pv = (void *)MapViewOfFile(_hfm, FILE_MAP_WRITE, 0, 0, 0);
|
|
if (!_pv)
|
|
{
|
|
CloseHandle(_hfm);
|
|
_hfm = NULL;
|
|
}
|
|
return _pv;
|
|
}
|
|
|
|
protected:
|
|
TCHAR *_pszFile;
|
|
void *_pv;
|
|
private:
|
|
HANDLE _hfm;
|
|
BOOL _fCreated;
|
|
BOOL _fUseMutex;
|
|
CCicMutexHelperStatic _mutexhlp;
|
|
};
|
|
|
|
class CCicFileMapping : public CCicFileMappingStatic
|
|
{
|
|
public:
|
|
CCicFileMapping(TCHAR *pszFile = NULL, CCicMutex *pmutex = NULL)
|
|
{
|
|
BaseInit();
|
|
Init(pszFile, pmutex );
|
|
}
|
|
|
|
virtual ~CCicFileMapping()
|
|
{
|
|
Finalize();
|
|
}
|
|
};
|
|
|
|
class CCicEvent
|
|
{
|
|
public:
|
|
CCicEvent(TCHAR *psz = NULL)
|
|
{
|
|
_psz = psz;
|
|
_hEvent = NULL;
|
|
}
|
|
|
|
~CCicEvent()
|
|
{
|
|
Uninit();
|
|
}
|
|
|
|
BOOL Create(SECURITY_ATTRIBUTES *psa, TCHAR *psz = NULL)
|
|
{
|
|
if (psz)
|
|
{
|
|
Assert(!_psz);
|
|
_psz = psz;
|
|
}
|
|
|
|
if (!_psz)
|
|
{
|
|
Assert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
Assert(!_hEvent);
|
|
|
|
_hEvent = CreateEvent(psa, FALSE, FALSE, _psz);
|
|
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::Create %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
|
|
Assert(_hEvent);
|
|
return _hEvent ? TRUE : FALSE;
|
|
}
|
|
|
|
BOOL Open(TCHAR *psz = NULL)
|
|
{
|
|
if (psz)
|
|
{
|
|
Assert(!_psz);
|
|
_psz = psz;
|
|
}
|
|
Assert(!_hEvent);
|
|
Assert(_psz);
|
|
|
|
_hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _psz);
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::Open %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
|
|
// Assert(_hEvent);
|
|
|
|
#ifdef DEBUG
|
|
if (!_hEvent)
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
TraceMsg(TF_EVENT, "OpenEvent error = %x %s\r\n", dwError, _psz);
|
|
}
|
|
#endif
|
|
|
|
return _hEvent ? TRUE : FALSE;
|
|
}
|
|
|
|
void Uninit()
|
|
{
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::Close %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
if (_hEvent)
|
|
CloseHandle(_hEvent);
|
|
_hEvent = NULL;
|
|
return;
|
|
}
|
|
|
|
BOOL Wait(DWORD dwMillisecouds)
|
|
{
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::Wait %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
DWORD dwWaitResult = WaitForSingleObject(_hEvent, dwMillisecouds);
|
|
if (dwWaitResult == WAIT_OBJECT_0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent Time Out", _szModule);
|
|
#endif
|
|
|
|
//
|
|
// assert here to debug stop.
|
|
//
|
|
// Assert(0);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD EventCheck()
|
|
{
|
|
Assert(_hEvent);
|
|
return WaitForSingleObject(_hEvent, 0);
|
|
}
|
|
|
|
DWORD MsgWait(DWORD dwWaitTime, DWORD dwWakeMask, DWORD dwFlags = 0)
|
|
{
|
|
Assert(_hEvent);
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::MsgWait %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
DWORD dwWaitResult;
|
|
dwWaitResult = MsgWaitForMultipleObjects(1,
|
|
&_hEvent,
|
|
FALSE,
|
|
dwWaitTime,
|
|
dwWakeMask);
|
|
#ifdef DEBUG
|
|
if (dwWaitResult == WAIT_TIMEOUT)
|
|
{
|
|
TraceMsg(TF_EVENT, "%s CCicEvent Time Out::timeout val=%d", _szModule, dwWaitTime);
|
|
}
|
|
#endif
|
|
return dwWaitResult;
|
|
}
|
|
|
|
void Set()
|
|
{
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::Set %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
SetEvent(_hEvent);
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
#ifdef DEBUG
|
|
TraceMsg(TF_EVENT, "%s CCicEvent::ReSet %x %s", _szModule, _hEvent, _psz);
|
|
#endif
|
|
ResetEvent(_hEvent);
|
|
}
|
|
|
|
void SetName(TCHAR *psz) {_psz = psz;}
|
|
|
|
|
|
private:
|
|
HANDLE _hEvent;
|
|
|
|
#ifdef DEBUG
|
|
TCHAR _szModule[MAX_PATH];
|
|
#endif
|
|
|
|
protected:
|
|
TCHAR *_psz;
|
|
};
|
|
|
|
class CCicTimer
|
|
{
|
|
public:
|
|
CCicTimer(DWORD dwMilliSeconds, BOOL fStart = TRUE)
|
|
{
|
|
_dwTimeOut = dwMilliSeconds / 10;
|
|
_dwTimeToWait = (DWORD)(-1);
|
|
_dwStartTime = (DWORD)(-1);
|
|
if (fStart)
|
|
Start();
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
_dwStartTime = GetTickCount() / 10;
|
|
_dwTimeToWait = _dwStartTime + _dwTimeOut;
|
|
}
|
|
|
|
BOOL IsTimerAtZero()
|
|
{
|
|
DWORD dwNow = GetTickCount() / 10;
|
|
if (_dwTimeToWait < dwNow)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL IsTimerPass(DWORD dwWaitSec)
|
|
{
|
|
DWORD dwNow = GetTickCount() / 10;
|
|
dwWaitSec /= 10;
|
|
if (dwNow - _dwStartTime > dwWaitSec)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
private:
|
|
DWORD _dwTimeToWait;
|
|
DWORD _dwStartTime;
|
|
DWORD _dwTimeOut;
|
|
};
|
|
|
|
|
|
|
|
#endif // CICMUTEX_H
|