📄 udfree.c
字号:
BOOL
WINAPI
UdprotUnchainSymEnt(LPSTAT lpTopic,
SYMPTR lpSymEnt)
{
LPUDMSG lpMsg;
int order;
SYMPTR lpSymTab, lpCompareEnt;
unsigned long SymHandle;
unsigned long old_count, uFloor, uCeiling, uCompare;
unsigned long huge *lpSymIndex; /* symbol table index array */
CHAINSCANNER message_scanner;
#ifdef DEBUG_CALL_TRAFFIC
if (Verbose)
debug("UdprotUnchainSymEnt( %Fp, %ul )",
lpTopic, (unsigned long) lpSymEnt->msIndex);
#endif
assert( lpTopic );
assert( lpSymEnt );
/* unlink the entry from the sorted list */
old_count = lpTopic->statSymUsed.item_count;
UnchainItem (&lpTopic->statSymUsed, (LPCHAINLINK) lpSymEnt);
/* return the symbol entry to the free list */
InsertItemAtHead (&lpTopic->statSymUnused, (LPCHAINLINK) lpSymEnt);
/*********************************************************************
* As of version 5.0 of the toolkit, this sample server includes
* a binary search for the symbol below.
*********************************************************************/
lpSymTab = (SYMPTR) lpTopic->statSymTab.first_member;
lpSymIndex = (unsigned long huge *) lpTopic->statSymInd.first_member;
uFloor = 0; /* binary search floor */
uCeiling = old_count - 1; /* binary search ceiling */
uCompare = (uFloor + uCeiling) >> 1; /* divide by 2 */
for (;;) {
/* get pointer to symbol in used list */
lpCompareEnt = &lpSymTab[lpSymIndex[uCompare]];
/* check symbol pointer */
if (lpCompareEnt == lpSymEnt) {
/* found it, check position in list of indexes */
if (uCompare < old_count - 1) {
/* collapse out old entry from indexes */
_fmemmove(&lpSymIndex[uCompare],
&lpSymIndex[uCompare + 1],
(size_t) ((old_count - 1 - uCompare) * sizeof(unsigned long)));
}
break;
}
/* compare used symbol's address to discarded symbol's address */
order = LogicalAddrCmp(lpSymEnt, lpCompareEnt);
if (order < 0) {
/* discarded entry is somewhere before lpCompareEnt */
if (uCompare == uFloor) {
/* bottomed out -- something went wrong */
ASSERT_ERROR;
} else {
/* keep looking before lpCompareEnt */
uCeiling = uCompare;
uCompare = (uFloor + uCeiling) >> 1;
}
} else {
/* discarded entry is somewhere after lpCompareEnt */
if (uCompare == uCeiling) {
/* topped out -- something went wrong */
ASSERT_ERROR;
} else {
/* check whether already at uFloor */
if (uCompare == uFloor) {
/* force end of loop */
uCompare = uFloor = uCeiling;
} else {
/* keep looking after lpCompareEnt */
uFloor = uCompare;
uCompare = (uFloor + uCeiling) >> 1;
}
}
} /* end - else (order >= 0) */
} /* end - for (;;) */
/** Now make sure none of the messages have a reference
back to the symbol entry being unchained. **/
/* get handle corresponding to the symbol */
SymHandle = lpSymEnt->msIndex + SYM_OFFSET;
/* check all read messages for this station */
lpMsg = (LPUDMSG) FindFirstItem (&lpTopic->statReadMsgList, SCAN_FROM_HEAD,
NULL, NULL, &message_scanner);
while( lpMsg != (LPUDMSG)NULL ) {
/* check whether message refers to this symbol */
if( lpMsg->mmFirstSym == SymHandle ) {
/* clear reference to this symbol */
lpMsg->mmFirstSym = 0;
}
if( lpMsg->mmLastSym == SymHandle ) {
/* clear reference to this symbol */
lpMsg->mmLastSym = 0;
}
/* get pointer to next message, if any */
lpMsg = (LPUDMSG) FindNextItem (&message_scanner);
}
/* check all write messages for this station */
lpMsg = (LPUDMSG) FindFirstItem (&lpTopic->statWriteMsgList, SCAN_FROM_HEAD,
NULL, NULL, &message_scanner);
while( lpMsg != (LPUDMSG)NULL ) {
/* check whether message refers to this symbol */
if( lpMsg->mmFirstSym == SymHandle ) {
/* clear reference to this symbol */
lpMsg->mmFirstSym = 0;
}
if( lpMsg->mmLastSym == SymHandle ) {
/* clear reference to this symbol */
lpMsg->mmLastSym = 0;
}
/* get pointer to next message, if any */
lpMsg = (LPUDMSG) FindNextItem (&message_scanner);
}
/* indicate success */
return TRUE;
} /* UdprotUnchainSymEnt */
/***********************************************************************/
/** unchain read message from queue for indicated station **/
void
WINAPI
UdprotUnchainMsg(LPSTAT lpTopic, LPUDMSG lpMsg)
{
LPPORT lpPort;
#ifdef DEBUG_CALL_TRAFFIC
if (Verbose)
debug("UdprotUnchainMsg( %Fp, %Fp )", lpTopic, lpMsg);
#endif
/* unchain the item from the station's read message queue */
UnchainItem (&lpTopic->statReadMsgList, (LPCHAINLINK) lpMsg);
/* check current station messages */
if (lpTopic->statCurMsg == lpMsg) {
/* station current message is this message, clear pointer */
lpTopic->statCurMsg = (LPUDMSG) NULL;
}
if (lpTopic->statCurReadMsg == lpMsg) {
/* station current read message is this message, clear pointer */
lpTopic->statCurReadMsg = (LPUDMSG) NULL;
}
/* check current port messages */
lpPort = lpTopic->statPort;
if (lpPort == (LPPORT) NULL) {
/* no port associated with station -- error */
ASSERT_ERROR;
} else {
if (lpPort->mbCurMsg == lpMsg) {
/* port current message is this message, clear pointer */
lpPort->mbCurMsg = (LPUDMSG) NULL;
/* indicate port is idle */
lpPort->mbState = PROT_IDLE;
}
}
} /* UdprotUnchainMsg */
/***********************************************************************/
/** unchain station from list
returns pointer to PORT associated with station, if successful **/
LPPORT
WINAPI
UdprotUnchainTopic(LPSTAT lpTopic)
{
LPPORT lpPort;
LPSTAT lpNextTopic;
if (lpTopic == (LPSTAT) NULL) {
/* do nothing, return NULL pointer */
ASSERT_ERROR;
return (LPPORT) NULL;
}
/* get pointer to port structure for this station */
lpPort = lpTopic->statPort;
if (lpPort == (LPPORT) NULL) {
/* do nothing, return NULL pointer */
return (LPPORT) NULL;
}
/* get pointer to next station, if any */
lpNextTopic = (LPSTAT) lpTopic->statChainLink.next_item.ptr;
/* unchain station from port's list */
UnchainItem (&lpPort->mbTopicList, (LPCHAINLINK) lpTopic);
/* check port's current station */
if (lpPort->mbCurTopic == lpTopic) {
/* deleting the station that is currently being processed */
if (lpNextTopic != (LPSTAT) NULL) {
/* use next station in list */
lpPort->mbCurTopic = lpNextTopic;
} else {
/* no next station, use first station in list, if any */
lpPort->mbCurTopic = (LPSTAT) lpPort->mbTopicList.first_item.ptr;
}
/* indicate protocol is idle */
lpPort->mbState = PROT_IDLE;
}
/* clear links to next and previous stations */
ClearChainLink (&lpTopic->statChainLink);
/* return pointer to port */
return (lpPort);
} /* UdprotUnchainTopic */
/***********************************************************************/
/** unchain port from list
returns handle to port, if successful **/
LPPORT
WINAPI
UdprotUnchainPort(LPPORT lpPort)
{
if (lpPort == (LPPORT) NULL) {
/* null pointer, indicate error */
ASSERT_ERROR;
return (LPPORT) NULL;
}
/* unchain port from list */
UnchainItem (&PortList, (LPCHAINLINK) lpPort);
/* return pointer to port */
return (lpPort);
} /* UdprotUnchainPort */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -