⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udfree.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -