windows-nt/Source/XPSP1/NT/net/homenet/alg/exe/collectionadapternotifysinks.cpp
2020-09-26 16:20:57 +08:00

286 lines
6.2 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 2000, Microsoft Corporation
Module Name:
CollectionAdapterNotifySinks.cpp
Abstract:
Implement a collection of the CPrimaryControlChannel.cpp & CSecondaryControlChannel
in a threa safe way.
Author:
JP Duplessis (jpdup) 08-Dec-2000
Revision History:
--*/
#include "PreComp.h"
#include "CollectionAdapterNotifySinks.h"
#include "AlgController.h"
CCollectionAdapterNotifySinks::~CCollectionAdapterNotifySinks()
{
RemoveAll();
}
//
// Add an already created Adapter
//
HRESULT
CCollectionAdapterNotifySinks::Add(
IN IAdapterNotificationSink* pAdapterSinkToAdd, // AdapterSink to be added at the collection
OUT DWORD* pdwNewCookie // Will be populated with the new unique id can be used later to retrieve the AdapterSink
)
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAdapterNotifySinks::Add")
if ( !pdwNewCookie )
{
MYTRACE_ERROR("Return Cookie address not supplied", 0);
return E_INVALIDARG;
}
CAdapterSinkBuket* pNewBuketToAdd = new CAdapterSinkBuket(pAdapterSinkToAdd);
if ( !pNewBuketToAdd )
return E_OUTOFMEMORY;
*pdwNewCookie = 1;
//
// Find a unique cookie
//
if ( m_ListOfAdapterSinks.empty() )
{
//
// List is empty so obviously the cookie '1' is unique
//
MYTRACE("First SINK Cookie is %d", *pdwNewCookie);
pNewBuketToAdd->m_dwCookie = *pdwNewCookie;
}
else
{
//
// Travers the collection and stop when the cookie is not found
// this schema could be optimize but the number of Sink is not expect to be large (1 per ALG modules)
//
MYTRACE("Current size %d", m_ListOfAdapterSinks.size() );
while ( pNewBuketToAdd->m_dwCookie==0 )
{
MYTRACE("Search for unique Cookie %d", *pdwNewCookie);
for ( LISTOF_ADAPTER_NOTIFICATION_SINK::iterator theIterator = m_ListOfAdapterSinks.begin();
theIterator != m_ListOfAdapterSinks.end();
theIterator++
)
{
CAdapterSinkBuket* pAdapterSinkBuket = (CAdapterSinkBuket*)(*theIterator);
if ( pAdapterSinkBuket->m_dwCookie == *pdwNewCookie )
break;
else
{
pNewBuketToAdd->m_dwCookie = *pdwNewCookie;
break; // ok we found a unique cookie
}
}
*pdwNewCookie = *pdwNewCookie + 1;
}
}
//
// Add Sync to Collection
//
m_ListOfAdapterSinks.push_back(pNewBuketToAdd);
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
//
// Remove a adapter from the list (Thead safe)
//
HRESULT
CCollectionAdapterNotifySinks::Remove(
IN DWORD dwCookieToRemove
)
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAdapterNotifySinks::Remove")
HRESULT hr = S_OK;
for ( LISTOF_ADAPTER_NOTIFICATION_SINK::iterator theIterator = m_ListOfAdapterSinks.begin();
theIterator != m_ListOfAdapterSinks.end();
theIterator++
)
{
CAdapterSinkBuket* pAdapterSinkBuket = (CAdapterSinkBuket*)(*theIterator);
if ( pAdapterSinkBuket->m_dwCookie == dwCookieToRemove )
{
delete pAdapterSinkBuket;
m_ListOfAdapterSinks.erase(theIterator);
return S_OK;
}
}
}
catch(...)
{
return E_FAIL;
}
return E_INVALIDARG; // if we are here that mean the cookie was not found
}
//
// When an adapter form the collection
//
HRESULT
CCollectionAdapterNotifySinks::RemoveAll()
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAdapterNotifySinks::RemoveAll")
//
// By deleting all the ControlChannel they will also cancel all their associated Redirection
//
LISTOF_ADAPTER_NOTIFICATION_SINK::iterator theIterator;
MYTRACE("Collection has %d item", m_ListOfAdapterSinks.size());
while ( m_ListOfAdapterSinks.size() > 0 )
{
theIterator = m_ListOfAdapterSinks.begin();
delete (*theIterator);
m_ListOfAdapterSinks.erase(theIterator);
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}
HRESULT
CCollectionAdapterNotifySinks::Notify(
eNOTIFY eAction,
IAdapterInfo* pIAdapterInfo
)
/*++
Routine Description:
For all AdapterSink inteface in the current collection do a notify with the given action ADDED,REMOVED,MODIFIED
Arguments:
eAction - ADDED, REMOVED, MODIFIED
pIAdapterInfo - Interface of the Adapter with the current action to be notify to alg modules
Return Value:
void - None
Environment:
--*/
{
try
{
ENTER_AUTO_CS
MYTRACE_ENTER("CCollectionAdapterNotifySinks::NotifySink")
MYTRACE("Collection size %d", m_ListOfAdapterSinks.size());
for ( LISTOF_ADAPTER_NOTIFICATION_SINK::iterator theIterator = m_ListOfAdapterSinks.begin();
theIterator != m_ListOfAdapterSinks.end();
theIterator++
)
{
CAdapterSinkBuket* pAdapterSinkBuket = (CAdapterSinkBuket*)(*theIterator);
MYTRACE("Will notify AdapterSink with cookie #%d", pAdapterSinkBuket->m_dwCookie);
switch ( eAction )
{
case eNOTIFY_ADDED:
pAdapterSinkBuket->m_pInterface->AdapterAdded(pIAdapterInfo);
break;
case eNOTIFY_REMOVED:
pAdapterSinkBuket->m_pInterface->AdapterRemoved(pIAdapterInfo);
break;
case eNOTIFY_MODIFIED:
pAdapterSinkBuket->m_pInterface->AdapterModified(pIAdapterInfo);
break;
}
}
}
catch(...)
{
return E_FAIL;
}
return S_OK;
}