mirror of https://github.com/tongzx/nt5src
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.
166 lines
5.1 KiB
166 lines
5.1 KiB
1) OUT params are not guaranteed to be initialized except in
|
|
the case of "Num of handles returned in an Enumeration" -
|
|
|
|
- like NumDests in RtmGetEnumDests etc.
|
|
|
|
|
|
2) Callbacks to entities - there are certain restrictions on
|
|
what Rtm calls can be used in the context of an RTM event
|
|
callback -
|
|
|
|
Entity Registration/De-registration callbacks:
|
|
|
|
RtmRegisterEntity
|
|
RtmDeregisterEntity
|
|
RtmGetRegdEntities
|
|
|
|
RtmGetInstances
|
|
RtmGetInstanceInfo
|
|
RtmGetAddrFamilyInfo
|
|
|
|
Route Timed-out callback:
|
|
|
|
Can call anything (as of now)
|
|
|
|
Change Notification callback:
|
|
|
|
RtmRegisterForChangeNotification
|
|
RtmDeregisterForChangeNotification
|
|
|
|
|
|
3) If RTM has to take care of the fact that no ops should be
|
|
allowed after deregistration -
|
|
|
|
//------------------------------------------------------
|
|
|
|
Code in RTMDeregisterEntity -
|
|
|
|
/*-----------------------------------------------------
|
|
This function marks the entity as deregistered thereby
|
|
preventing this entity from making any more operations.
|
|
|
|
It also waits until all pending operations on (or) by
|
|
this entity are completed before it start cleaning up
|
|
the state of the entity being deregistered.
|
|
|
|
If other entities have handles open on objects of this
|
|
entity, then this memory is reclaimed when these handles
|
|
are released.
|
|
|
|
Note that if this entity has handles open on objects
|
|
(routes and nexthops) owned by another entity, then we
|
|
have a case of a memory leak.
|
|
------------------------------------------------------*/
|
|
|
|
//
|
|
// Mark entity as deregistered to prevent more ops
|
|
//
|
|
|
|
try
|
|
{
|
|
Entity = GET_POINTER_FROM_HANDLE(RtmRegHandle);
|
|
|
|
#if DBG_HDL
|
|
if (Entity->ObjectHeader.TypeSign != ENTITY_ALLOC)
|
|
{
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
#endif
|
|
|
|
// Block all new ops by flagging a deregister
|
|
|
|
OldState = InterlockedExchangeAdd(&Entity->State,
|
|
ENTITY_STATE_DEREGISTERED);
|
|
|
|
if (OldState >= ENTITY_STATE_DEREGISTERED)
|
|
{
|
|
// We have already de-registered here
|
|
|
|
InterlockedExchangeAdd(&Entity->State,
|
|
(-1) * ENTITY_STATE_DEREGISTERED);
|
|
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
//
|
|
// Block while waiting for active ops to finish
|
|
//
|
|
|
|
while (Entity->State != ENTITY_STATE_DEREGISTERED)
|
|
{
|
|
Sleep(0);
|
|
}
|
|
|
|
and
|
|
|
|
Code for validating handle in other functions -
|
|
|
|
try
|
|
{
|
|
Entity = GET_POINTER_FROM_HANDLE(RtmRegHandle);
|
|
|
|
#if DBG_HDL
|
|
if (Entity->ObjectHeader.TypeSign != ENTITY_ALLOC)
|
|
{
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
#endif
|
|
|
|
if (InterlockedIncrement(&Entity->State) >= ENTITY_STATE_DEREGISTERED)
|
|
{
|
|
// We have already de-registered here
|
|
|
|
InterlockedDecrement(&Entity->State);
|
|
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
}
|
|
except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return ERROR_INVALID_HANDLE;
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
|
|
4) In case you wanted to use Interlocked Ops on lists -
|
|
|
|
//
|
|
// Single Link List manipulation using Interlocked Ops
|
|
//
|
|
|
|
#define InterlockedPushEntryList(ListHead, Entry) \
|
|
while (TRUE) \
|
|
{ \
|
|
(Entry)->Next = (ListHead)->Next; \
|
|
if (InterlockedCompareExchangePointer(&((ListHead)->Next),\
|
|
(Entry), \
|
|
(Entry)->Next) \
|
|
== (Entry)->Next) \
|
|
{ \
|
|
break; \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define InterlockedPopEntryList(ListHead, Entry) \
|
|
while (TRUE) \
|
|
{ \
|
|
Entry = (ListHead)->Next; \
|
|
if (Entry == NULL) \
|
|
{ \
|
|
break; \
|
|
} \
|
|
\
|
|
if (InterlockedCompareExchangePointer(&((ListHead)->Next),\
|
|
((Entry)->Next), \
|
|
(Entry) \
|
|
!= (Entry)) \
|
|
{ \
|
|
continue; \
|
|
} \
|
|
}
|