📄 distnodelib.c
字号:
distNodeNumNodesOperational--; for (i = 0; i < DIST_NODE_MAX_HOOKS; i++) { if (distNodeCrashedHook[i] != NULL) (* (distNodeCrashedHook[i])) (distNodeId); } } pNodeFound->nodeState = DIST_NODE_STATE_CRASHED; } DIST_NODE_DB_UNLOCK; return (pNodeFound); }/***************************************************************************** distNodeLocalGetId - returns the local node id (VxFusion option)** This routine returns the id of the local node.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Local node ID.* NOMANUAL*/DIST_NODE_ID distNodeLocalGetId (void) { return (distNodeLocalId); }/***************************************************************************** distNodeLocalSetId - sets the local node id (VxFusion option)** This routine sets the id of the local node.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: N/A* NOMANUAL*/void distNodeLocalSetId ( DIST_NODE_ID myNodeId /* node ID */ ) { distNodeLocalId = myNodeId; }/***************************************************************************** distNodeLocalSetState - sets the state of the local node (VxFusion option)** This routine sets the state of the local node.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: N/A* NOMANUAL*/void distNodeLocalSetState ( int state /* new state for local node */ ) { distNodeLocalState = state; }/***************************************************************************** distNodeLocalGetState - get state of the local node (VxFusion option)** This routine returns the state of the local node.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Node state.* NOMANUAL*/int distNodeLocalGetState (void) { return (distNodeLocalState); }/***************************************************************************** distNodeGetNumNodes - returns the number of nodes in a specified state (VxFusion option)** This routine returns the number of nodes currently in a specified state.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Count of nodes, or -1 if <typeSet> is invalid.* NOMANUAL*/int distNodeGetNumNodes ( int typeSet /* state to look for */ ) { switch (typeSet) { case DIST_NODE_NUM_NODES_ALL: return (distNodeNumNodesAll); case DIST_NODE_NUM_NODES_ALIVE: return (distNodeNumNodesAlive); case DIST_NODE_NUM_NODES_OPERATIONAL: return (distNodeNumNodesOperational); default: return (-1); } }/***************************************************************************** distNodeGetGodfatherId - get the id of our godfather (VxFusion option)** This routine returns the id of this node's godfather.* If no godfather is available, distNodeGetGodfatherId() returns ERROR,* else OK.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, if godfather exists.* NOMANUAL*/STATUS distNodeGetGodfatherId ( DIST_NODE_ID * nodeId /* where to return godfather ID */ ) { if ((*nodeId = distNodeGodfatherId) == DIST_IF_BROADCAST_ADDR) return (ERROR); return (OK); }#ifdef UNDEFINED/* This routine does not seem to be used *//***************************************************************************** distNodeTouch - touch a node (increment message counter) (VxFusion option)** This routine touches a node.** NOTE: Must take <distNodeDbLock> before.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: OK, unless <distNodeId> is invalid.* NOMANUAL*/STATUS distNodeTouch ( DIST_NODE_ID distNodeId /* ID of node to touch */ ) { DIST_NODE_DB_NODE * pDistNodeFound; if ((pDistNodeFound = distNodeFindById (distNodeId)) == NULL) { /* Node does not exist. Should never happen. */ distStat.nodeDBNoMatch++; return (ERROR); } DIST_NODE_IN_PKT_INC(pDistNodeFound); return (OK); }#endif/***************************************************************************** distNodeEach - call a routine for each node in the database (VxFusion option)** This routine calls a user-supplied routine once for each node.* The user-supplied routine should return TRUE if distNodeEach() is to* continue calling it with the remaining nodes, or FALSE if it is done and* distNodeEach() can exit.** distNodeEach() returns NULL if traversed whole database, or pointer to* node entry that distNodeEach() ended with.** NOTE: Takes <distNodeDbLock>.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Pointer to last node visited.* NOMANUAL*/DIST_NODE_DB_NODE * distNodeEach ( FUNCPTR routine, /* function to call at each node */ int routineArg /* argument to function */ ) { DIST_NODE_DB_NODE * lastNode; distNodeDbLock (); lastNode = (DIST_NODE_DB_NODE *) hashTblEach (distNodeDbId, routine, routineArg); distNodeDbUnlock (); return (lastNode); }/***************************************************************************** distNodeCleanup - Flush out all communication queues (VxFusion option)** This routine flushes all communication queues of <pNode>. It is only* called from two places in distNodeReassemble() which takes the node* DB lock first.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: N/A* NOMANUAL*/LOCAL void distNodeCleanup ( DIST_NODE_DB_NODE * pNode /* node to clean-up */ ) { DIST_TBUF_HDR * pPkt; DIST_NODE_COMM * pCommUnicast, *pCommBroadcast; pCommUnicast = &pNode->nodeUnicast; pCommBroadcast = &pNode->nodeBroadcast; /* * Clean up communication structures of bootstrapping * node. * * Delete all unicast packets waiting for reassemly. */ while (pCommUnicast->pCommQReass) { DIST_TBUF_HDR_DEQUEUE (pCommUnicast->pCommQReass, pPkt); DIST_TBUF_FREEM (pPkt); } /* * Dequeue all unicast packets waiting for a slide in * the window. Wakeup sender. */ while (pCommUnicast->pCommQWinOut) { DIST_TBUF_HDR_DEQUEUE (pCommUnicast->pCommQWinOut, pPkt); pPkt->pTBufHdrTm->tmStatus = DIST_TM_STATUS_UNREACH; semGive (&pPkt->pTBufHdrTm->tmWait4); /* distNodePktSend() frees packet */ } /* * Dequeue all unicast packets waiting for an ACK. * Wakeup sender. */ while (pCommUnicast->pCommQAck) { DIST_TBUF_HDR_DEQUEUE (pCommUnicast->pCommQAck, pPkt); pPkt->pTBufHdrTm->tmStatus = DIST_TM_STATUS_UNREACH; semGive (&pPkt->pTBufHdrTm->tmWait4); /* distNodePktSend() frees packet */ } bzero ((char *) pCommUnicast->pCommCompleted, DIST_NODE_BFLD_SIZEOF (DIST_IF_RNG_BUF_SZ)); pCommUnicast->commPktNextExpect = 0; pCommUnicast->commAckNextExpect = 0; pCommUnicast->commPktNextSend = 0; pCommUnicast->commAckDelayed = FALSE; /* Delete all broadcast packets waiting for reassembly. */ while (pCommBroadcast->pCommQReass) { DIST_TBUF_HDR_DEQUEUE (pCommBroadcast->pCommQReass, pPkt); DIST_TBUF_FREEM (pPkt); } bzero ((char *) pCommBroadcast->pCommCompleted, DIST_NODE_BFLD_SIZEOF (DIST_IF_RNG_BUF_SZ)); }/***************************************************************************** distNodeGetReassembled - get a reassembled packet (VxFusion option)** This routine gets a reassembled data packet. It takes the node DB lock.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Ptr to tbuf header.* NOMANUAL*/DIST_TBUF_HDR * distNodeGetReassembled ( DIST_NODE_COMM * pComm /* ptr to comm node */ ) { DIST_TBUF_HDR * pHead; /* head of tbufs */ short nextExpected; /* next expected seq number */ DIST_TBUF_HDR * pNext; /* next tbuf */ distNodeDbLock (); pHead = pComm->pCommQNextDeliver; nextExpected = pComm->commPktNextExpect; if (pHead && pHead->tBufHdrId == nextExpected && DIST_NODE_BTST (pComm->pCommCompleted, nextExpected)) { /* Remove the packet from the reassembly queue. */ DIST_TBUF_HDR_UNLINK (pComm->pCommQReass, pHead); if (nextExpected == (DIST_IF_RNG_BUF_SZ - 1)) pNext = pComm->pCommQReass; else pNext = pHead->pTBufHdrNext; if (pNext && winAdd (nextExpected, 1) != pNext->tBufHdrId) { /* if a complete packet is missing, we fall in here */ pComm->pCommQNextDeliver = NULL; } else { /* next packet in ring is the one, we expect next */ pComm->pCommQNextDeliver = pNext; } distNodeDbUnlock (); /* UNLOCK */#ifdef DIST_NODE_REPORT /* this is a hack */ printf ("distNodeGetReassembled: return %p (type %d/%d)\n", pHead, *((char *) (DIST_TBUF_GET_NEXT (pHead)->pTBufData)), *((char *) (DIST_TBUF_GET_NEXT (pHead)->pTBufData) + 1));#endif return (pHead); } distNodeDbUnlock (); /* UNLOCK */#ifdef DIST_NODE_REPORT printf ("distNodeGetReassembled: no packet available\n");#endif return (NULL); }/***************************************************************************** distNodeReassemble - reassemble a packet (VxFusion option)** This routine takes a telegram and tries to reassemble it with other* fragments already stored in the reassembly list.* distNodeReassemble() updates the communication windows managed* within the database.** If <nodeIdSrc> is unknown by now, distNodeReassemble() creates a* new node in the node database. Creating a node is only allowed when* receiving a XACK telegram in bootstrap mode or a BOOTSTRAP telegram.** If a packet has been reassembled successfully, distNodeReassemble()* returns a pointer to the communication structure. Else a NULL pointer* is returned.** NOTE: Takes <distNodeDbLock>.** AVAILABILITY* This routine is distributed as a component of the unbundled distributed* message queues option, VxFusion.** RETURNS: Ptr to comm node.* NOMANUAL*/DIST_NODE_COMM * distNodeReassemble ( DIST_NODE_ID nodeIdSrc, /* source node */ int prio, /* priority */ DIST_TBUF * pTBufNew /* ptr to tbuf */ ) { DIST_NODE_DB_NODE * pNode; DIST_NODE_DB_NODE * pNodeSrc; DIST_NODE_COMM * pCommIn; DIST_NODE_COMM * pCommOut; DIST_TBUF_HDR * pReassHdr; DIST_TBUF_HDR * pReassHdrPrev; DIST_TBUF_HDR * pTBufAck;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -