📄 refcnt.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
refcnt.c
Abstract:
This module exports Reference Counting support functions. By
including a Reference Count Control Block (REF_CNT) in a
dynamic type, and using this API, a Reference scheme can be
implemented for that type.
Revision History:
--*/
//
// Include Files
//
#include "irda.h"
VOID
ReferenceInit
(
IN PREF_CNT pRefCnt,
PVOID InstanceHandle,
VOID (*DeleteHandler)( PVOID )
)
/*++
Routine Description:
ReferenceInit initializes and adds one reference to the
supplied Reference Control Block. If provided, an instance
handle and delete handler are saved for use by the ReferenceRemove
function when all references to the instance are removed.
Arguments:
pRefCnt - pointer to uninitialized Reference Control Block
InstanceHandle - handle to the managed instance.
DeleteHandler - pointer to delete function, NULL is OK.
Return Value:
The function's value is VOID.
--*/
{
DEBUGMSG( DBG_REF,(TEXT("ReferenceInit( 0x%x, 0x%x, 0x%x )\n"),
pRefCnt, InstanceHandle, DeleteHandler ));
if (pRefCnt) {
// Set the reference to 1 and save the instance
// handle and the delete handler.
pRefCnt->Count = 0;
pRefCnt->Instance = InstanceHandle;
pRefCnt->DeleteHandler = DeleteHandler;
#if DBG
pRefCnt->Sig = REF_SIG;
RtlZeroMemory(pRefCnt->Tags, sizeof(REF_TAG) * TAG_CNT);
pRefCnt->Tags[0].Tag = 'LTOT';
#endif
} else {
ASSERT(0);
}
}
VOID
ReferenceAdd
(
IN PREF_CNT pRefCnt
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
if (pRefCnt) {
InterlockedIncrement(&pRefCnt->Count);
} else {
ASSERT(0);
}
// DEBUGMSG( DBG_REF,( "R+%d\n", pRefCnt->Count ));
}
#ifndef UNDER_CE
// CE doesn't support this since we don't have InterlockedExchangeAdd.
VOID
ReferenceAddCount
(
IN PREF_CNT pRefCnt,
IN UINT Count
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
ASSERT( pRefCnt->Count > 0 );
pRefCnt->Count += Count;
}
#endif // !UNDER_CE
PVOID
ReferenceRemove
(
IN PREF_CNT pRefCnt
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
// UINT Count;
// UINT NoReference;
if (pRefCnt) {
if (pRefCnt->Count) {
// If the decremented count is non zero return the instance handle
if( InterlockedDecrement(&pRefCnt->Count) > 0 )
{
// DEBUGMSG( DBG_REF,( "R-%d\n", pRefCnt->Count ));
// DEBUGMSG( DBG_REF,( "ReferenceRemove:remaining: %d\n", pRefCnt->Count ));
return( pRefCnt->Instance );
}
// Delete this instance if a delete handler is available
if( pRefCnt->DeleteHandler )
{
DEBUGMSG( DBG_REF,(TEXT("Executing DeleteHandler\n")));
(pRefCnt->DeleteHandler)( pRefCnt->Instance );
}
} else {
// Trap remove reference on a zero count
ASSERT(0);
}
} else {
// Trap NULL pRefCnt
ASSERT(0);
}
// Indicate no active references to this instance
return( NULL );
}
//
// API Test Support
//
#if DBG
VOID
ReferenceApiTest( VOID )
{
REF_CNT RefCnt;
DEBUGMSG( 1,( TEXT("\nReferenceApiTest\n")));
DEBUGMSG( 1,( TEXT("\nTest #1: NULL delete handler\n")));
ReferenceInit( &RefCnt, &RefCnt, NULL );
ReferenceAdd( &RefCnt );
ReferenceAdd( &RefCnt );
ReferenceAdd( &RefCnt );
while( ReferenceRemove( &RefCnt ) )
{
;
}
DEBUGMSG( 1,( TEXT("\nTest #2: Delete Handler - TBD\n")));
}
VOID
ReferenceAddDbg(PREF_CNT pRefCnt, ULONG Tag)
{
int i;
ASSERT(pRefCnt->Sig == REF_SIG);
for (i = 1; i < TAG_CNT; i++)
{
if (pRefCnt->Tags[i].Tag == 0 || pRefCnt->Tags[i].Tag == Tag)
{
pRefCnt->Tags[i].Tag = Tag;
pRefCnt->Tags[i].Count++;
break;
}
}
ASSERT(i < TAG_CNT);
ReferenceAdd(pRefCnt);
pRefCnt->Tags[0].Count = pRefCnt->Count;
}
VOID
ReferenceRemoveDbg(PREF_CNT pRefCnt, ULONG Tag)
{
int i;
ASSERT(pRefCnt->Sig == REF_SIG);
for (i = 1; i < TAG_CNT; i++)
{
if (pRefCnt->Tags[i].Tag == Tag)
{
pRefCnt->Tags[i].Count -= 1;
if (pRefCnt->Tags[i].Count == 0)
pRefCnt->Tags[i].Tag = 0;
break;
}
}
pRefCnt->Tags[0].Count = pRefCnt->Count - 1;
ReferenceRemove(pRefCnt);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -