/*========================================================================== * * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved. * * File: AsyncOp.h * Content: Async Operation Object Header File *@@BEGIN_MSINTERNAL * History: * Date By Reason * ==== == ====== * 04/08/00 mjn Created * 04/11/00 mjn Added DIRECTNETOBJECT bilink for CAsyncOps * 04/16/00 mjn Added ASYNC_OP_SEND and ASYNC_OP_USER_HANDLE * mjn Added SetStartTime() and GetStartTime() * 04/20/00 mjn Added ASYNC_OP_RECEIVE_BUFFER * 04/22/00 mjn Added ASYNC_OP_REQUEST * 05/02/00 mjn Added m_pConnection to track Connection over life of AsyncOp * 07/08/00 mjn Added m_bilinkParent * 07/17/00 mjn Added signature to CAsyncOp * 07/27/00 mjn Added m_dwReserved and changed locking for parent/child bilinks * 08/05/00 mjn Added ASYNC_OP_COMPLETE,ASYNC_OP_CANCELLED,ASYNC_OP_INTERNAL flags * mjn Added m_bilinkActiveList * 01/09/01 mjn Added ASYNC_OP_CANNOT_CANCEL,SetCannotCancel(),IsCannotCancel() * 02/08/01 mjn Added m_pCancelEvent,m_dwCancelThreadID * 05/23/01 mjn Added ClearCannotCancel() *@@END_MSINTERNAL * ***************************************************************************/ #ifndef __ASYNC_OP_H__ #define __ASYNC_OP_H__ #undef DPF_SUBCOMP #define DPF_SUBCOMP DN_SUBCOMP_CORE //********************************************************************** // Constant definitions //********************************************************************** #define ASYNC_OP_CHILD 0x0001 #define ASYNC_OP_PARENT 0x0002 #define ASYNC_OP_USE_PARENT_OP_DATA 0x0004 #define ASYNC_OP_CANNOT_CANCEL 0x0010 #define ASYNC_OP_COMPLETE 0x0100 #define ASYNC_OP_CANCELLED 0x0200 #define ASYNC_OP_INTERNAL 0x8000 //********************************************************************** // Macro definitions //********************************************************************** //********************************************************************** // Structure definitions //********************************************************************** typedef enum { ASYNC_OP_CONNECT, ASYNC_OP_DISCONNECT, ASYNC_OP_ENUM_QUERY, ASYNC_OP_ENUM_RESPONSE, ASYNC_OP_LISTEN, ASYNC_OP_SEND, ASYNC_OP_RECEIVE_BUFFER, ASYNC_OP_REQUEST, ASYNC_OP_UNKNOWN, ASYNC_OP_USER_HANDLE, #ifndef DPNBUILD_NOMULTICAST ASYNC_OP_LISTEN_MULTICAST, ASYNC_OP_CONNECT_MULTICAST_SEND, ASYNC_OP_CONNECT_MULTICAST_RECEIVE, #endif // ! DPNBUILD_NOMULTICAST } ASYNC_OP_TYPE; class CAsyncOp; class CConnection; class CRefCountBuffer; class CServiceProvider; class CSyncEvent; typedef struct _DIRECTNETOBJECT DIRECTNETOBJECT; typedef void (*PFNASYNCOP_COMPLETE)(DIRECTNETOBJECT *const,CAsyncOp *const); typedef union { DN_SEND_OP_DATA SendOpData; #ifndef DPNBUILD_ONLYONEADAPTER DN_LISTEN_OP_DATA ListenOpData; DN_CONNECT_OP_DATA ConnectOpData; #endif // ! DPNBUILD_ONLYONEADAPTER DN_ENUM_QUERY_OP_DATA EnumQueryOpData; DN_ENUM_RESPONSE_OP_DATA EnumResponseOpData; } DN_OP_DATA; //********************************************************************** // Variable definitions //********************************************************************** //********************************************************************** // Function prototypes //********************************************************************** //********************************************************************** // Class prototypes //********************************************************************** // class for Async Operations class CAsyncOp { public: #undef DPF_MODNAME #define DPF_MODNAME "CAsyncOp::FPMAlloc" static BOOL FPMAlloc( void* pvItem, void* pvContext ) { CAsyncOp* pAsyncOp = (CAsyncOp*)pvItem; pAsyncOp->m_Sig[0] = 'A'; pAsyncOp->m_Sig[1] = 'S'; pAsyncOp->m_Sig[2] = 'Y'; pAsyncOp->m_Sig[3] = 'N'; pAsyncOp->m_dwReserved = 0; if (!DNInitializeCriticalSection(&pAsyncOp->m_cs)) { return(FALSE); } #ifdef DBG pAsyncOp->m_bilinkAsyncOps.Initialize(); #endif // DBG pAsyncOp->m_bilinkActiveList.Initialize(); pAsyncOp->m_bilinkParent.Initialize(); pAsyncOp->m_bilinkChildren.Initialize(); memset( &pAsyncOp->m_OpData,0x00,sizeof(DN_OP_DATA) ); return(TRUE); }; #undef DPF_MODNAME #define DPF_MODNAME "CAsyncOp::FPMInitialize" static void FPMInitialize( void* pvItem, void* pvContext ) { CAsyncOp* pAsyncOp = (CAsyncOp*)pvItem; pAsyncOp->m_pdnObject = static_cast(pvContext); pAsyncOp->m_dwFlags = 0; pAsyncOp->m_lRefCount = 1; pAsyncOp->m_OpType = ASYNC_OP_UNKNOWN; pAsyncOp->m_pParent = NULL; pAsyncOp->m_handle = 0; pAsyncOp->m_dwOpFlags = 0; pAsyncOp->m_pvContext = NULL; pAsyncOp->m_hProtocol = NULL; pAsyncOp->m_pvOpData = NULL; pAsyncOp->m_dwStartTime = 0; pAsyncOp->m_dpnid = 0; pAsyncOp->m_hr = DPNERR_GENERIC; pAsyncOp->m_phr = NULL; pAsyncOp->m_pConnection = NULL; pAsyncOp->m_pSP = NULL; pAsyncOp->m_pRefCountBuffer = NULL; pAsyncOp->m_pSyncEvent = NULL; pAsyncOp->m_pCancelEvent = NULL; pAsyncOp->m_dwCancelThreadID = 0; pAsyncOp->m_pfnCompletion = NULL; pAsyncOp->m_dwFirstFrameRTT = -1; pAsyncOp->m_dwFirstFrameRetryCount = -1; // pAsyncOp->m_dwReserved = 0; #ifdef DBG DNASSERT(pAsyncOp->m_bilinkAsyncOps.IsEmpty()); #endif // DBG DNASSERT(pAsyncOp->m_bilinkActiveList.IsEmpty()); DNASSERT(pAsyncOp->m_bilinkParent.IsEmpty()); DNASSERT(pAsyncOp->m_bilinkChildren.IsEmpty()); }; #undef DPF_MODNAME #define DPF_MODNAME "CAsyncOp::FPMRelease" static void FPMRelease( void* pvItem ) { CAsyncOp* pAsyncOp = (CAsyncOp*)pvItem; pAsyncOp->m_dwFlags |= 0xffff0000; #ifdef DBG DNASSERT(pAsyncOp->m_bilinkAsyncOps.IsEmpty()); #endif // DBG DNASSERT(pAsyncOp->m_bilinkActiveList.IsEmpty()); DNASSERT(pAsyncOp->m_bilinkParent.IsEmpty()); DNASSERT(pAsyncOp->m_bilinkChildren.IsEmpty()); DNASSERT(pAsyncOp->m_pvOpData == NULL); }; #undef DPF_MODNAME #define DPF_MODNAME "CAsyncOp::FPMDealloc" static void FPMDealloc( void* pvItem ) { CAsyncOp* pAsyncOp = (CAsyncOp*)pvItem; DNDeleteCriticalSection(&pAsyncOp->m_cs); }; void ReturnSelfToPool( void ); #undef DPF_MODNAME #define DPF_MODNAME "CAsyncOp::AddRef" void AddRef(void) { LONG lRefCount; DNASSERT(m_lRefCount > 0); lRefCount = DNInterlockedIncrement(const_cast(&m_lRefCount)); DPFX(DPFPREP, 3,"CAsyncOp::AddRef [0x%lx] RefCount [0x%lx]",this,lRefCount); }; void CAsyncOp::Release( void ); void Lock( void ) { DNEnterCriticalSection( &m_cs ); }; void Unlock( void ) { DNLeaveCriticalSection( &m_cs ); }; void SetOpType( const ASYNC_OP_TYPE OpType ) { m_OpType = OpType; }; ASYNC_OP_TYPE GetOpType( void ) const { return( m_OpType ); }; void MakeParent( void ) { m_dwFlags |= ASYNC_OP_PARENT; }; BOOL IsParent( void ) const { if (m_dwFlags & ASYNC_OP_PARENT) return(TRUE); return(FALSE); }; #undef DPF_MODNAME #define DPF_MODNAME "CAsyncOp::MakeChild" void MakeChild( CAsyncOp *const pParent ) { DNASSERT(pParent != NULL); pParent->AddRef(); m_pParent = pParent; m_bilinkChildren.InsertBefore(&m_pParent->m_bilinkParent); m_dwFlags |= ASYNC_OP_CHILD; }; BOOL IsChild( void ) const { if (m_dwFlags & ASYNC_OP_CHILD) return(TRUE); return(FALSE); }; CAsyncOp *GetParent( void ) const { return( m_pParent ); }; void CAsyncOp::Orphan( void ); void SetHandle( const DPNHANDLE handle ) { m_handle = handle; }; DPNHANDLE GetHandle( void ) const { return( m_handle ); }; void SetOpFlags( const DWORD dwOpFlags ) { m_dwOpFlags = dwOpFlags; }; DWORD GetOpFlags( void ) const { return( m_dwOpFlags ); }; void SetContext( void *const pvContext ) { m_pvContext = pvContext; }; void *GetContext( void ) const { return( m_pvContext ); }; void SetProtocolHandle( const HANDLE hProtocol ) { m_hProtocol = hProtocol; }; HANDLE GetProtocolHandle( void ) const { return( m_hProtocol ); }; void SetOpData( void *const pvOpData ) { m_pvOpData = pvOpData; }; void *GetOpData( void ) const { return( m_pvOpData ); }; void SetStartTime( const DWORD dwStartTime ) { m_dwStartTime = dwStartTime; }; DWORD GetStartTime( void ) const { return( m_dwStartTime ); }; void SetDPNID( const DPNID dpnid ) { m_dpnid = dpnid; }; DPNID GetDPNID( void ) const { return( m_dpnid ); }; void SetResult( const HRESULT hr ) { m_hr = hr; }; HRESULT GetResult( void ) const { return( m_hr ); }; void SetFirstFrameRTT( const DWORD dwFirstFrameRTT ) { m_dwFirstFrameRTT = dwFirstFrameRTT; }; DWORD GetFirstFrameRTT( void ) const { return ( m_dwFirstFrameRTT ); }; void SetFirstFrameRetryCount( const DWORD dwFirstFrameRetryCount ) { m_dwFirstFrameRetryCount = dwFirstFrameRetryCount; }; DWORD GetFirstFrameRetryCount( void ) const { return ( m_dwFirstFrameRetryCount ); }; void SetResultPointer( volatile HRESULT *const phr ) { m_phr = phr; }; volatile HRESULT *GetResultPointer( void ) const { return( m_phr ); }; void CAsyncOp::SetConnection( CConnection *const pConnection ); CConnection *GetConnection (void ) const { return( m_pConnection ); }; void CAsyncOp::SetSP( CServiceProvider *const pSP ); CServiceProvider *GetSP( void ) const { return( m_pSP ); }; void CAsyncOp::SetRefCountBuffer( CRefCountBuffer *const pRefCountBuffer ); CRefCountBuffer *GetRefCountBuffer( void ) const { return( m_pRefCountBuffer ); }; void SetSyncEvent( CSyncEvent *const pSyncEvent ) { m_pSyncEvent = pSyncEvent; }; CSyncEvent *GetSyncEvent( void ) const { return( m_pSyncEvent ); }; void SetCancelEvent( CSyncEvent *const pSyncEvent ) { m_pCancelEvent = pSyncEvent; }; CSyncEvent *GetCancelEvent( void ) const { return( m_pCancelEvent ); }; void SetCancelThreadID( const DWORD dwCancelThreadID ) { m_dwCancelThreadID = dwCancelThreadID; }; DWORD GetCancelThreadID( void ) const { return( m_dwCancelThreadID ); }; void SetCompletion( PFNASYNCOP_COMPLETE pfn ) { m_pfnCompletion = pfn; }; void SetReserved( const DWORD dw ) { m_dwReserved = dw; }; void SetComplete( void ) { m_dwFlags |= ASYNC_OP_COMPLETE; }; BOOL IsComplete( void ) const { if (m_dwFlags & ASYNC_OP_COMPLETE) { return( TRUE ); } return( FALSE ); }; void SetCancelled( void ) { m_dwFlags |= ASYNC_OP_CANCELLED; }; BOOL IsCancelled( void ) const { if (m_dwFlags & ASYNC_OP_CANCELLED) { return( TRUE ); } return( FALSE ); }; void SetInternal( void ) { m_dwFlags |= ASYNC_OP_INTERNAL; }; BOOL IsInternal( void ) const { if (m_dwFlags & ASYNC_OP_INTERNAL) { return( TRUE ); } return( FALSE ); }; void ClearCannotCancel( void ) { m_dwFlags &= (~ASYNC_OP_CANNOT_CANCEL); }; void SetCannotCancel( void ) { m_dwFlags |= ASYNC_OP_CANNOT_CANCEL; }; BOOL IsCannotCancel( void ) const { if (m_dwFlags & ASYNC_OP_CANNOT_CANCEL) { return( TRUE ); } return( FALSE ); }; void ClearUseParentOpData( void ) { m_dwFlags &= (~ASYNC_OP_USE_PARENT_OP_DATA); }; void SetUseParentOpData( void ) { m_dwFlags |= ASYNC_OP_USE_PARENT_OP_DATA; }; BOOL IsUseParentOpData( void ) const { if (m_dwFlags & ASYNC_OP_USE_PARENT_OP_DATA) { return( TRUE ); } return( FALSE ); }; DN_SEND_OP_DATA *GetLocalSendOpData( void ) { return( &m_OpData.SendOpData ); }; #ifndef DPNBUILD_ONLYONEADAPTER DN_CONNECT_OP_DATA *GetLocalConnectOpData( void ) { return( &m_OpData.ConnectOpData ); }; DN_LISTEN_OP_DATA *GetLocalListenOpData( void ) { return( &m_OpData.ListenOpData ); }; #endif // ! DPNBUILD_ONLYONEADAPTER DN_ENUM_QUERY_OP_DATA *GetLocalEnumQueryOpData( void ) { return( &m_OpData.EnumQueryOpData ); }; DN_ENUM_RESPONSE_OP_DATA *GetLocalEnumResponseOpData( void ) { return( &m_OpData.EnumResponseOpData ); }; #ifdef DBG CBilink m_bilinkAsyncOps; #endif // DBG CBilink m_bilinkActiveList; // Active AsyncOps CBilink m_bilinkParent; // Starting point for children CBilink m_bilinkChildren; // Other children sharing this parent private: BYTE m_Sig[4]; // Signature DWORD volatile m_dwFlags; LONG volatile m_lRefCount; ASYNC_OP_TYPE m_OpType; // Operation Type CAsyncOp *m_pParent; // Parent Async Operation DPNHANDLE m_handle; // Async Operation Handle DWORD m_dwOpFlags; void *m_pvContext; HANDLE m_hProtocol; // Protocol Operation Handle void *m_pvOpData; // Operation specific data DWORD m_dwStartTime; DPNID m_dpnid; HRESULT volatile m_hr; volatile HRESULT *m_phr; CConnection *m_pConnection; // Send Target connection - released CServiceProvider *m_pSP; // Service Provider - released CRefCountBuffer *m_pRefCountBuffer; // Refernce Count Buffer - released CSyncEvent *m_pSyncEvent; // Sync Event - set at release CSyncEvent *m_pCancelEvent; // Cancel event - prevent completion from returning DWORD m_dwCancelThreadID; // Cancelling thread's ID (prevent deadlocking) PFNASYNCOP_COMPLETE m_pfnCompletion; // Completion function - called #ifndef DPNBUILD_ONLYONETHREAD DNCRITICAL_SECTION m_cs; #endif // !DPNBUILD_ONLYONETHREAD DIRECTNETOBJECT *m_pdnObject; DWORD m_dwFirstFrameRTT; DWORD m_dwFirstFrameRetryCount; DN_OP_DATA m_OpData; DWORD m_dwReserved; // INTERNAL - RESERVED FOR DEBUG ! }; #undef DPF_MODNAME #endif // __ASYNC_OP_H__