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.
208 lines
4.8 KiB
208 lines
4.8 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: connection.cpp
|
|
* Content: Connection routines
|
|
*@@BEGIN_MSINTERNAL
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 10/13/99 mjn Created
|
|
* 03/02/00 mjn Conversion to class
|
|
* 04/08/00 mjn Added ServiceProvider to Connection object
|
|
* mjn Disconnect uses new CAsyncOp class
|
|
* 04/18/00 mjn CConnection tracks connection status better
|
|
* 04/21/00 mjn Disconnection through DNPerformDisconnect
|
|
* 07/20/00 mjn Changed Release() behaviour and beefed up Disconnect()
|
|
* 07/28/00 mjn Added m_bilinkConnections to CConnection
|
|
* 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
|
|
* 02/12/01 mjn Fixed CConnection::GetEndPt() to track calling thread and added ReleaseEndPt()
|
|
* 04/04/01 mjn CConnection list off DirectNetObject guarded by proper critical section
|
|
*@@END_MSINTERNAL
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dncorei.h"
|
|
|
|
|
|
// CConnection::ReturnSelfToPool
|
|
//
|
|
// Return object to FPM
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnection::ReturnSelfToPool"
|
|
|
|
void CConnection::ReturnSelfToPool( void )
|
|
{
|
|
DPFX(DPFPREP, 8,"Parameters: (none)");
|
|
|
|
g_ConnectionPool.Release( this );
|
|
|
|
DPFX(DPFPREP, 8,"Returning");
|
|
};
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnection::Release"
|
|
|
|
void CConnection::Release(void)
|
|
{
|
|
LONG lRefCount;
|
|
|
|
DPFX(DPFPREP, 8,"Parameters: (none)");
|
|
|
|
DNASSERT(m_lRefCount > 0);
|
|
lRefCount = DNInterlockedDecrement(const_cast<LONG*>(&m_lRefCount));
|
|
DPFX(DPFPREP, 3,"Connection::Release [0x%p] RefCount [0x%lx]",this,lRefCount);
|
|
|
|
if (lRefCount == 0)
|
|
{
|
|
//
|
|
// Remove from the bilink of outstanding CConnection objects
|
|
//
|
|
DNEnterCriticalSection(&m_pdnObject->csConnectionList);
|
|
m_bilinkConnections.RemoveFromList();
|
|
DNLeaveCriticalSection(&m_pdnObject->csConnectionList);
|
|
|
|
if (m_pSP)
|
|
{
|
|
m_pSP->Release();
|
|
m_pSP = NULL;
|
|
}
|
|
m_dwFlags = 0;
|
|
m_lRefCount = 0;
|
|
m_hEndPt = NULL;
|
|
ReturnSelfToPool();
|
|
}
|
|
|
|
DPFX(DPFPREP, 8,"Returning");
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnection::GetEndPt"
|
|
|
|
HRESULT CConnection::GetEndPt(HANDLE *const phEndPt,CCallbackThread *const pCallbackThread)
|
|
{
|
|
HRESULT hResultCode;
|
|
|
|
DNASSERT(phEndPt != NULL);
|
|
DNASSERT(pCallbackThread != NULL);
|
|
|
|
Lock();
|
|
if ((m_Status == CONNECTED) || (m_Status == CONNECTING))
|
|
{
|
|
//
|
|
// Add the calling thread to the bilink to that the endpoint will
|
|
// not be invalidated (through IndicateConnectionTerminated) until
|
|
// this thread is done with the endpoint.
|
|
//
|
|
pCallbackThread->GetCallbackThreadsBilink()->InsertBefore(&m_bilinkCallbackThreads);
|
|
*phEndPt = m_hEndPt;
|
|
hResultCode = DPN_OK;
|
|
}
|
|
else
|
|
{
|
|
hResultCode = DPNERR_NOCONNECTION;
|
|
}
|
|
Unlock();
|
|
|
|
return(hResultCode);
|
|
};
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnection::ReleaseEndPt"
|
|
|
|
void CConnection::ReleaseEndPt(CCallbackThread *const pCallbackThread)
|
|
{
|
|
DNASSERT(pCallbackThread != NULL);
|
|
|
|
Lock();
|
|
pCallbackThread->GetCallbackThreadsBilink()->RemoveFromList();
|
|
if (m_dwThreadCount != 0)
|
|
{
|
|
//
|
|
// If there is a thread count,
|
|
// decrement it
|
|
// if this is the last count
|
|
// set the event
|
|
//
|
|
m_dwThreadCount--;
|
|
if (m_dwThreadCount == 0)
|
|
{
|
|
DNASSERT(m_pThreadEvent != NULL);
|
|
if (m_pThreadEvent)
|
|
{
|
|
m_pThreadEvent->Set();
|
|
}
|
|
}
|
|
}
|
|
Unlock();
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnection::SetSP"
|
|
|
|
void CConnection::SetSP( CServiceProvider *const pSP )
|
|
{
|
|
DPFX(DPFPREP, 8,"Parameters: pSP [0x%p]",pSP);
|
|
|
|
DNASSERT( pSP != NULL );
|
|
|
|
pSP->AddRef();
|
|
m_pSP = pSP;
|
|
|
|
DPFX(DPFPREP, 8,"Returning");
|
|
}
|
|
|
|
|
|
|
|
// CConnection::Disconnect
|
|
//
|
|
// Initiate a disconnection. If this is successful, eventually we will receive an IndicateConnectionTerminated
|
|
// which we should use to remove a reference (from the Protocol).
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CConnection::Disconnect"
|
|
|
|
void CConnection::Disconnect( void )
|
|
{
|
|
BOOL fDisconnect;
|
|
|
|
DPFX(DPFPREP, 8,"Parameters: (none)");
|
|
|
|
DNASSERT(m_pdnObject != NULL);
|
|
|
|
fDisconnect = FALSE;
|
|
Lock();
|
|
if ((m_Status == CONNECTING) || (m_Status == CONNECTED))
|
|
{
|
|
if (m_hEndPt != NULL)
|
|
{
|
|
m_Status = DISCONNECTING;
|
|
fDisconnect = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_Status = INVALID;
|
|
}
|
|
}
|
|
Unlock();
|
|
|
|
if (fDisconnect)
|
|
{
|
|
#ifndef DPNBUILD_NOMULTICAST
|
|
if (m_dwFlags & CONNECTION_FLAG_MULTICAST_RECEIVER)
|
|
{
|
|
DNUserDestroySenderContext(m_pdnObject,m_pvContext);
|
|
}
|
|
#endif // DPNBUILD_NOMULTICAST
|
|
DNPerformDisconnect(m_pdnObject,this,m_hEndPt,FALSE);
|
|
}
|
|
|
|
DPFX(DPFPREP, 8,"Returning");
|
|
}
|