mirror of https://github.com/tongzx/nt5src
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.
127 lines
3.0 KiB
127 lines
3.0 KiB
// Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
|
|
// CUnknown.cpp
|
|
#include "precomp.h"
|
|
#include <objidl.h>
|
|
#include <cominit.h>
|
|
|
|
#include <objbase.h>
|
|
#include <comdef.h>
|
|
|
|
#include "CUnknown.h"
|
|
|
|
#include "factory.h"
|
|
|
|
|
|
extern const char g_szTypeLibName[];
|
|
|
|
long CUnknown::s_cActiveComponents = 0L;
|
|
|
|
/*****************************************************************************/
|
|
// Constructor
|
|
/*****************************************************************************/
|
|
CUnknown::CUnknown()
|
|
: m_cRef(1),
|
|
m_hEventThread(NULL),
|
|
m_eStatus(Pending)
|
|
{
|
|
InterlockedIncrement(&s_cActiveComponents);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
// Destructor
|
|
/*****************************************************************************/
|
|
CUnknown::~CUnknown()
|
|
{
|
|
InterlockedDecrement(&s_cActiveComponents);
|
|
if(m_hEventThread)
|
|
{
|
|
::CloseHandle(m_hEventThread);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
// FinalRelease - called by Release before it deletes the component
|
|
/*****************************************************************************/
|
|
void CUnknown::FinalRelease()
|
|
{
|
|
// If we have an event thread...
|
|
if(m_eStatus != Pending)
|
|
{
|
|
// Let the event thread know that it can stop...
|
|
m_eStatus = PendingStop;
|
|
// Hold here until the event thread has stopped...
|
|
DWORD dwWait = ::WaitForSingleObject(
|
|
m_hEventThread,
|
|
1000 * 60 * 20);
|
|
|
|
if(dwWait == WAIT_TIMEOUT)
|
|
{
|
|
// Something is most likely wrong....
|
|
// If it takes 20 minutes, we will terminate
|
|
// the thread, even though it is understood
|
|
// that TerminateThread will leak some
|
|
// resources, as that is better than
|
|
// leaving the thread running infinitely.
|
|
::TerminateThread(
|
|
m_hEventThread,
|
|
-1L);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
// CUnknown default initialization
|
|
/*****************************************************************************/
|
|
STDMETHODIMP CUnknown::Init()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
return S_OK ;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
// IUnknown implementation
|
|
/*****************************************************************************/
|
|
STDMETHODIMP CUnknown::QueryInterface(const IID& iid, void** ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(iid == IID_IUnknown)
|
|
{
|
|
*ppv = static_cast<IUnknown*>(this);
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CUnknown::AddRef()
|
|
{
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CUnknown::Release()
|
|
{
|
|
ULONG ulRet = 0L;
|
|
InterlockedDecrement(&m_cRef);
|
|
if (m_cRef == 0)
|
|
{
|
|
FinalRelease();
|
|
delete this;
|
|
}
|
|
else
|
|
{
|
|
ulRet = m_cRef;
|
|
}
|
|
return ulRet;
|
|
}
|
|
|