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

📄 osptransids.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 2 页
字号:
void                                /* returns nothing */OSPPTransIdPurge(    OSPTTRANSID *ospvSentinel,    OSPTPROVIDER *ospvProvider){    OSPTTRANSID   *ptransid = OSPC_OSNULL;    unsigned long now       = 0;#ifdef TN_TRANSDBG    char          buf[20];#endif    /* Get the current time. Anything older will be deleted. */    now = OSPPTransIdSecNow();    for ( ptransid = ospvSentinel->ospmTransactionIdOlderPtr;          (ptransid != ospvSentinel) && (ptransid->ospmTransactionIdExpires < now);          ptransid = ospvSentinel->ospmTransactionIdNewerPtr)    {        /* this one's expired, remove it from the list */        ptransid->ospmTransactionIdOlderPtr->ospmTransactionIdNewerPtr = ptransid->ospmTransactionIdNewerPtr;        ptransid->ospmTransactionIdNewerPtr->ospmTransactionIdOlderPtr = ptransid->ospmTransactionIdOlderPtr;#ifdef TN_TRANSDBG	OSPM_MEMSET(&buf, 0, sizeof(buf));	sprintf(buf, "%u", ptransid->ospmTransactionId);	fprintf(stderr, "\n ****del TID: %s, @=0x%p\n", buf, ptransid);#endif        /* and then delete it completely */        OSPPTransIdRemove(ptransid, ospvProvider);    }}/*-----------------------------------------------------------------------*//* OSPPTransIdRemove - remove a transaction ID from the ordered tree */void                                /* no return value */OSPPTransIdRemove(    OSPTTRANSID *ospvTransId,       /* transaction ID to remove */    OSPTPROVIDER *ospvProvider      /* osp provider object */){    OSPTTRANSID *splice     = OSPC_OSNULL;          /* node to be spliced */    OSPTTRANSID *child      = OSPC_OSNULL;          /* child of spliced node */    int         errorcode   = OSPC_ERR_NO_ERROR;    OSPTTRANSID** root      = OSPC_OSNULL;          /* tree's root */        /*     * Yep, the worst part of any binary tree stuff -- removing     * a single node from the tree. (Why is this routine always     * left as an exercise to the reader in algorithm and data     * structures text books?) The approach is pretty standard,     * though. Three cases:     *     * 1) Node has no children! Piece of cake, just update its     *    parent to point to null.     *     * 2) Node has only a single child. Not too much harder, just     *    "splice" the current node out of the tree. (I.e. update     *     its parent to point to the node's only child.)     *     * 3) Node has two children. This one's the hard one. We "splice"     *    out the node's successor and replace the current node     *    with its successor. See details below.     */    /* figure out which node to splice out */    if ((ospvTransId->ospmTransactionIdLessPtr == 0) || (ospvTransId->ospmTransactionIdMorePtr == 0))    {        /*         * If the node has no more than one child, then it is         * itself the one to remove from the tree. This actually         * takes care of cases 1 and 2 above, since we'll be         * sure to "splice" correctly even the node has no         * children.         */                 splice = ospvTransId;    }    else    {        /*         * Okay, the node we want to delete has two children. That         * means we can't simply splice it out, because we'd have         * to leave one of those poor children orphaned. What we         * want to do is find the "successor" of the node to         * delete. The successor is the next greatest node after         * the current one (the smallest transaction ID greater         * that the current node's.) In a tree structure, the         * successor is the left-most node (the "tidLessPtr" path)         * in the right (the "tidMorePtr" path) subtree.         */         splice = ospvTransId->ospmTransactionIdMorePtr;         while (splice->ospmTransactionIdLessPtr)         {            splice = splice->ospmTransactionIdLessPtr;         }    }    /*     * Now we've found the node to splice out. Next figure out which     * of that node's children is going to get "promoted".     */    if (splice->ospmTransactionIdLessPtr)    {        child = splice->ospmTransactionIdLessPtr;    }    else    {        /*         * This handles case 1 in the introduction. If the node         * had no children, the pChild will end up being null.         */                 child = splice->ospmTransactionIdMorePtr;    }    /*     * Okay, we've identified the child to promote, change it's     * parent to the spliced node's parent.     */    if (child)    {        if(!(*(child->ospmTransactionIdParent) == splice->ospmTransactionIdLessPtr) ||           !(*(child->ospmTransactionIdParent) == splice->ospmTransactionIdMorePtr) )        {            errorcode = OSPC_ERR_TRANSID;        }        if(errorcode == OSPC_ERR_NO_ERROR)        {            child->ospmTransactionIdParent = splice->ospmTransactionIdParent;        }    }    /*     * Last part of the splice: update the parent to point to the     * new child.     */         if(errorcode == OSPC_ERR_NO_ERROR)    {        *(splice->ospmTransactionIdParent) = child;        /*         * Final cleanup, if the node we spliced out wasn't the actual         * node to delete, then we need to replace the deleted node's         * contents with the spliced node's.         */        if (splice != ospvTransId)        {            /* good place for some checks */            if(!(splice->ospmTransactionIdOlderPtr->ospmTransactionIdNewerPtr == splice) ||               !(splice->ospmTransactionIdNewerPtr->ospmTransactionIdOlderPtr == splice))            {                errorcode = OSPC_ERR_TRANSID;            }                    if(errorcode == OSPC_ERR_NO_ERROR)            {                /* first extract the spliced node from the linked list */                splice->ospmTransactionIdOlderPtr->ospmTransactionIdNewerPtr = ospvTransId;                splice->ospmTransactionIdNewerPtr->ospmTransactionIdOlderPtr = ospvTransId;                /* now insert the existing node into the linked list */                ospvTransId->ospmTransactionIdOlderPtr = splice->ospmTransactionIdOlderPtr;                ospvTransId->ospmTransactionIdNewerPtr = splice->ospmTransactionIdNewerPtr;                /* finally, update the existing node's actual data */                ospvTransId->ospmTransactionId = splice->ospmTransactionId;                ospvTransId->ospmTransactionIdExpires = splice->ospmTransactionIdExpires;            }        }    }    if(splice != OSPC_OSNULL)    {        /* wbr: double check to see if splice is root, if so, update the root:	 */	root = OSPPProviderGetTransIdRoot( ospvProvider );	if (*root == splice)   /* about to prune off the root */	{	   *root = child;#ifdef TN_TRANSDBG	   fprintf( stderr, "\n ********** updating new root to point to 0x%p\n", 			   *root);#endif	}        /* release the memory */        OSPPTransIdDelete(splice);             }}/*-----------------------------------------------------------------------*//* OSPPTransIdSecNow - current time in seconds since midnight 1Jan1970 */unsigned long                       /* returns current time in seconds */OSPPTransIdSecNow(){    time_t now;		time(&now);    return(now);}/*-----------------------------------------------------------------------*//* OSPPTransIdTimeAdd - add transaction in time-ordered linked list */void                                /* no return value */OSPPTransIdTimeAdd(    OSPTTRANSID     *ospvTransId,   /* transaction ID to add */    OSPTPROVIDER    *ospvProvider){    OSPTTRANSID *curr       = OSPC_OSNULL;               /* current position on list */    OSPTTRANSID *sentinel   = OSPPProviderGetTransIdSentinel(ospvProvider);    int         errorcode   = OSPC_ERR_NO_ERROR;     /*     * We put this transaction on the list in sorted order. To     * do that, we start with the newest transaction and move     * to older ones until we find where the current transaction     * needs to go.     */    if(sentinel != OSPC_OSNULL)    {        for (curr = sentinel->ospmTransactionIdOlderPtr;             ((curr != sentinel) && (curr->ospmTransactionIdExpires > ospvTransId->ospmTransactionIdExpires));            )        {            /*             * The loop iteration could be moved into the for statement,             * but we wanted to go ahead and use the for loop to check             * pointer consistency using the assert statements below.             * If the asserts were the only thing inside the braces, then             * some compilers might complain when a non-assert (e.g.             * production version) is built. To be on the safe side,             * then, we've moved the iteration statement inside the             * body of the for statement.             */            curr = curr->ospmTransactionIdOlderPtr;            /* now do the checks we were just talking about */            if(!(curr->ospmTransactionIdOlderPtr->ospmTransactionIdNewerPtr == curr) &&               !(curr->ospmTransactionIdOlderPtr->ospmTransactionIdOlderPtr == curr))            {               errorcode = OSPC_ERR_TRANSID;               break;            }        }        if(errorcode == OSPC_ERR_NO_ERROR)        {            /* Now just plop the new transaction in the list */            ospvTransId->ospmTransactionIdOlderPtr = curr;            ospvTransId->ospmTransactionIdNewerPtr = curr->ospmTransactionIdNewerPtr;            curr->ospmTransactionIdNewerPtr->ospmTransactionIdOlderPtr = ospvTransId;            curr->ospmTransactionIdNewerPtr = ospvTransId;        }    }}/*------------------------------------------- * OSPPTransIDTreeDelete - delete the whole tree */voidOSPPTransIDTreeDelete(    OSPTPROVIDER    *ospvProvider){    OSPTTRANSID *ptransid = OSPC_OSNULL;    OSPTTRANSID *sentinel = OSPPProviderGetTransIdSentinel(ospvProvider);    /* LOCK GLOBAL DATA NOW */	OSPPProviderLockTransIdMutex(ospvProvider);    if(sentinel != OSPC_OSNULL)    {        for ( ptransid = sentinel->ospmTransactionIdOlderPtr;              (ptransid != sentinel);              ptransid = sentinel->ospmTransactionIdOlderPtr)        {            /* remove it from the list */            ptransid->ospmTransactionIdOlderPtr->ospmTransactionIdNewerPtr = ptransid->ospmTransactionIdNewerPtr;            ptransid->ospmTransactionIdNewerPtr->ospmTransactionIdOlderPtr = ptransid->ospmTransactionIdOlderPtr;            /* and then delete it completely */            OSPPTransIdRemove(ptransid, ospvProvider);        }    }    /* RELEASE LOCK ON GLOBAL DATA NOW */	OSPPProviderUnLockTransIdMutex(ospvProvider);    return;}/*-----------------------------------------------------------------------*//* tnTransById - list transactions in order of ID */#ifdef TN_TRANSDBGvoid                                /* no return value */tnTransById(    OSPTPROVIDER *ospvProvider){    /* LOCK MUTEX ON GLOBAL DATA NOW */	OSPPProviderLockTransIdMutex(ospvProvider);    /*     * Since this function is really only for debug purposes, we     * can be inefficient and use a recursive algorithm.     */    tnPrintTree(*(OSPPProviderGetTransIdRoot(ospvProvider)));    /* RELEASE MUTEX ON GLOBAL DATA NOW */	OSPPProviderUnLockTransIdMutex(ospvProvider);}#endif/*-----------------------------------------------------------------------*//* tnPrintTree - print the contents of a tree of transactions */#ifdef TN_TRANSDBGvoidtnPrintTree(    OSPTTRANSID *pTrans){    char buf[30];    if (pTrans)    {        /* use the opportunity to check consistency */        assert( (pTrans->ospmTransactionIdLessPtr == 0) ||                (pTrans->ospmTransactionIdLessPtr->ospmTransactionIdParent == &(pTrans->ospmTransactionIdLessPtr)) );        assert( (pTrans->ospmTransactionIdMorePtr == 0) ||                (pTrans->ospmTransactionIdMorePtr->ospmTransactionIdParent == &(pTrans->ospmTransactionIdMorePtr)) );                tnPrintTree(pTrans->ospmTransactionIdLessPtr);/* #ifdef _DEBUG */		OSPM_MEMSET(&buf, 0, sizeof(buf));		sprintf(buf, "%u", pTrans->ospmTransactionId);        fprintf(stderr, "\n** TID:%s, @=0x%p\n", buf, pTrans);/* #endif */        tnPrintTree(pTrans->ospmTransactionIdMorePtr);    }}#endif/*-----------------------------------------------------------------------*//* tnTransByTime - list transactions in order of expiration time */#ifdef TN_TRANSDBGvoid                                /* no return value */tnTransByTime(    OSPTPROVIDER *ospvProvider){    OSPTTRANSID *pTrans;    char buf[30];    /* LOCK MUTEX ON GLOBAL DATA NOW */	OSPPProviderLockTransIdMutex(ospvProvider);    for (pTrans=(OSPPProviderGetTransIdSentinel(ospvProvider))->ospmTransactionIdNewerPtr;          pTrans != OSPPProviderGetTransIdSentinel(ospvProvider);         pTrans = pTrans->ospmTransactionIdNewerPtr)    {        assert(pTrans->ospmTransactionIdNewerPtr->ospmTransactionIdOlderPtr == pTrans);        assert(pTrans->ospmTransactionIdOlderPtr->ospmTransactionIdNewerPtr == pTrans);#ifdef _DEBUG        OSPM_MEMSET(&buf, 0, sizeof(buf));		sprintf(buf, "%d", pTrans->ospmTransactionId);         fprintf(stderr, "\nAt %s transaction %s expires.", ctime( &(pTrans->ospmTransactionIdExpires)), buf);        /*afxDump << "\nAt " <<pTrans->tidExpires << ", transaction " << buf << "expires.";*/#endif    }    /* RELEASE SEMAPHORE ON GLOBAL DATA NOW */	OSPPProviderUnLockTransIdMutex(ospvProvider);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -