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.
 
 
 
 
 
 

256 lines
4.6 KiB

#ifndef _MISCHLPR_H_
#define _MISCHLPR_H_
#include <objbase.h>
#include "dbg.h"
#include "tfids.h"
#define UNREF_PARAM(a)
#define IID_PPV_ARG(IType, ppType) IID_##IType, reinterpret_cast<void**>(static_cast<IType**>(ppType))
class CRefCounted
{
#ifdef DEBUG
private:
void _TraceHelper(LPCTSTR pszOper, ULONG cRef, LPCTSTR pszObjName,
LPCSTR pszFile, const int iLine)
{
LPTSTR pszFinal;
WCHAR szwBuf[MAX_PATH + 12];
CHAR szBuf[MAX_PATH + 12];
int c = lstrlenA(pszFile);
LPCSTR pszFileName;
while (c && ('\\' != *(pszFile + c)))
{
--c;
}
pszFileName = pszFile + c + 1;
wsprintfA(szBuf, "<%s, %d>", pszFileName, iLine);
#ifdef UNICODE
pszFinal = szwBuf;
MultiByteToWideChar(CP_ACP, 0, szBuf, lstrlenA(szBuf) + 1, szwBuf,
sizeof(szwBuf) / sizeof(WCHAR));
#else
pszFinal = szBuf;
#endif
if (pszObjName)
{
TRACE(TF_RCADDREF | TF_NOFILEANDLINE, TEXT("%s {%s} %s: %d"),
pszFinal, pszObjName, pszOper, cRef);
}
else
{
TRACE(TF_NOFILEANDLINE | TF_RCADDREF, TEXT("%s %s: %d"), pszFinal,
pszOper, cRef);
}
}
protected:
void _RCCreate(LPCSTR pszFile, const int iLine)
{
_TraceHelper(TEXT(" Create"), 1, _pszRCAddRefName, pszFile, iLine);
}
LPTSTR _pszRCAddRefName;
public:
ULONG _RCGetRefCount()
{
return _cRef;
}
virtual ULONG RCAddRef(LPCSTR pszFile, const int iLine)
{
ULONG cRef = ::InterlockedIncrement((LONG*)&_cRef);
_TraceHelper(TEXT(" AddRef"), cRef, _pszRCAddRefName, pszFile, iLine);
return cRef;
}
virtual ULONG RCRelease(LPCSTR pszFile, const int iLine)
{
ULONG cRef = ::InterlockedDecrement((LONG*)&_cRef);
_TraceHelper(TEXT("Release"), cRef, _pszRCAddRefName, pszFile, iLine);
if (!cRef)
{
delete this;
}
return cRef;
}
#define RCAddRef() RCAddRef(__FILE__, __LINE__)
#define RCRelease() RCRelease(__FILE__, __LINE__)
#else
public:
ULONG RCAddRef() { return ::InterlockedIncrement((LONG*)&_cRef); }
ULONG RCRelease()
{
ULONG cRef = ::InterlockedDecrement((LONG*)&_cRef);
if (!cRef)
{
delete this;
}
return cRef;
}
#endif
CRefCounted() : _cRef(1)
#ifdef DEBUG
, _pszRCAddRefName(NULL)
#endif
{}
virtual ~CRefCounted() {}
private:
ULONG _cRef;
};
class CRefCountedCritSect : public CRefCounted, public CRITICAL_SECTION
{};
class CCriticalSection : CRITICAL_SECTION
{
public:
void Init()
{
InitializeCriticalSection(this);
_fInited = TRUE;
#ifdef DEBUG
_iLevel = 0;
#endif
}
void Enter()
{
ASSERT(_fInited);
EnterCriticalSection(this);
#ifdef DEBUG
++_iLevel;
#endif
}
void Leave()
{
ASSERT(_fInited);
#ifdef DEBUG
--_iLevel;
#endif
LeaveCriticalSection(this);
}
void Delete()
{
if (_fInited)
{
_fInited = FALSE;
DeleteCriticalSection(this);
}
}
BOOL IsInitialized()
{
return _fInited;
}
BOOL _fInited;
#ifdef DEBUG
BOOL IsInside()
{
ASSERT(_fInited);
return _iLevel;
}
DWORD _iLevel;
#endif
};
class CThreadTask
{
public:
virtual ~CThreadTask() {}
public:
// Uses CreateThread, delete 'this' at the end
HRESULT RunWithTimeout(DWORD dwTimeout);
// Uses Thread Pool, delete 'this' at the end
HRESULT Run();
// Run on 'this' thread, does NOT delete 'this' at the end
HRESULT RunSynchronously();
protected:
virtual HRESULT _DoStuff() = 0;
private:
static DWORD WINAPI _ThreadProc(void* pv);
};
template<typename TDataPtr>
HRESULT _AllocMemoryChunk(DWORD cbSize, TDataPtr* pdataOut)
{
HRESULT hr;
*pdataOut = (TDataPtr)LocalAlloc(LPTR, cbSize);
if (*pdataOut)
{
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
template<typename TDataPtr>
HRESULT _DupMemoryChunk(TDataPtr pdata, DWORD cbSize, TDataPtr* pdataOut)
{
HRESULT hr;
*pdataOut = (TDataPtr)LocalAlloc(LPTR, cbSize);
if (*pdataOut)
{
CopyMemory((void*)*pdataOut, pdata, cbSize);
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
template<typename TDataPtr>
HRESULT _FreeMemoryChunk(TDataPtr pdata)
{
HRESULT hr = S_OK;
if (LocalFree((HLOCAL)pdata))
{
hr = E_FAIL;
}
return hr;
}
#endif //_MISCHLPR_H_