windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/smtp/server/cleanback.h

150 lines
3.3 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//+------------------------------------------------------------
//
// Copyright (C) 1999, Microsoft Corporation
//
// File: cleanback.h
//
// Contents: Implements Cleanup callback interface
//
// Classes: CCleanBack
//
// Description: The intention is this object will be used as a part of
// other objects (member variable or inheritence).
// Therefore, the IUnknown passed in is NOT referenced.
//
// History:
// jstamerj 1999/09/27 17:58:50: Created.
//
//-------------------------------------------------------------
#include "mailmsg.h"
#include "spinlock.h"
class CCleanBack :
public IMailMsgRegisterCleanupCallback
{
public:
CCleanBack(IUnknown *pUnknown)
{
m_pListHead = NULL;
m_pIUnknown = pUnknown;
InitializeSpinLock(&m_spinlock);
}
~CCleanBack()
{
CallCallBacks();
}
VOID CallCallBacks()
{
//
// Call all registered callbacks while destroying the list
//
CCallBack *pCallback;
while(m_pListHead) {
//
// Dequeue from head of list
//
AcquireSpinLock(&m_spinlock);
pCallback = m_pListHead;
if(pCallback)
m_pListHead = pCallback->GetNext();
ReleaseSpinLock(&m_spinlock);
//
// Make the call
//
if(pCallback) {
pCallback->Call(m_pIUnknown);
delete pCallback;
}
}
}
STDMETHOD (RegisterCleanupCallback) (
IMailMsgCleanupCallback *pICallBack,
PVOID pvContext)
{
CCallBack *pCCallBack;
if(pICallBack == NULL)
return E_POINTER;
pCCallBack = new CCallBack(
pICallBack,
pvContext);
if(pCCallBack == NULL)
return E_OUTOFMEMORY;
//
// Insert object into list
//
AcquireSpinLock(&m_spinlock);
pCCallBack->SetNext(m_pListHead);
m_pListHead = pCCallBack;
ReleaseSpinLock(&m_spinlock);
return S_OK;
}
class CCallBack {
public:
CCallBack(IMailMsgCleanupCallback *pICallBack, PVOID pvContext)
{
m_pICallBack = pICallBack;
m_pICallBack->AddRef();
m_pvContext = pvContext;
m_pNext = NULL;
}
~CCallBack()
{
m_pICallBack->Release();
}
VOID Call(IUnknown *pIUnknown)
{
m_pICallBack->CleanupCallback(
pIUnknown,
m_pvContext);
}
VOID SetNext(CCallBack *pCCallBack)
{
m_pNext = pCCallBack;
}
CCallBack * GetNext()
{
return m_pNext;
}
private:
IMailMsgCleanupCallback *m_pICallBack;
PVOID m_pvContext;
CCallBack *m_pNext;
};
public:
//IUnknown
STDMETHOD (QueryInterface) (
REFIID iid,
PVOID *ppv)
{
return m_pIUnknown->QueryInterface(
iid,
ppv);
}
STDMETHOD_ (ULONG, AddRef) ()
{
return m_pIUnknown->AddRef();
}
STDMETHOD_ (ULONG, Release) ()
{
return m_pIUnknown->Release();
}
private:
SPIN_LOCK m_spinlock;
CCallBack *m_pListHead;
IUnknown *m_pIUnknown;
};