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

📄 distgaplib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	distPktGapTry.tryHdr.pktType = DIST_PKT_TYPE_GAP;	distPktGapTry.tryHdr.pktSubType = DIST_PKT_TYPE_GAP_TRY;	distPktGapTry.tryId = htons (pDistGrpDbNode->grpDbId);  /* uint16 */	strcpy ((char *) &distPktGapTry.tryName,			(char *) &pDistGrpDbNode->grpDbName);#ifdef DIST_GAP_REPORT	printf ("distGapTry: send a TRY for `%s'/%d to node %ld\n",			(char *) &pDistGrpDbNode->grpDbName,			pDistGrpDbNode->grpDbId, distNodeId);#endif	status = distNetSend (distNodeId, (DIST_PKT *) &distPktGapTry,			sizeof (distPktGapTry), WAIT_FOREVER, DIST_GAP_PRIO);	return (status);	}/********************************************************************************* distGapInput - GAP incoming message dispatcher** NOMANUAL*/LOCAL DIST_STATUS distGapInput	(	DIST_NODE_ID	distNodeIdSrc,	DIST_TBUF_HDR	*pTBufHdr	)	{	char		distPktGap[DIST_PKT_GAP_MAX_LEN];	distTBufCopy (DIST_TBUF_GET_NEXT (pTBufHdr), 0, (char *) &distPktGap,			DIST_PKT_GAP_MAX_LEN);	switch (((DIST_PKT *) &distPktGap)->pktSubType)	{	/*	 * We have received a TRY. Look if there are conflicts. If not,	 * respond with OK, else compare the node ids (buddy algorithm)	 * and send either OK or REJECT.	 */	case DIST_PKT_TYPE_GAP_TRY:		{		DIST_PKT_GAP_TRY	*pDistPktGapTry = (DIST_PKT_GAP_TRY *) &distPktGap;		DIST_GRP_DB_NODE	*pGrpFoundById;		DIST_GRP_DB_NODE	*pGrpFoundByName;		DIST_GRP_STATE		grpState;		/* Convert tryId (uint16) to host order */		pDistPktGapTry->tryId = ntohs (pDistPktGapTry->tryId);		/*		 * What can we read out form the TRY-id?		 *		 * If we receive a TRY for an id that is greater the one		 * we would try, we have missed a TRY.		 * This can happen, if some node sent a TRY, which is correctly		 * received by some other node, but not by us--retransmission		 * is enforced, but takes some time. The other node immediately		 * starts sendind a TRY of its own, which in turn is received by us		 * correctly. As you can see, it seams for us that we have		 * missed a TRY--in fact the missing TRY is just delayed.		 *		 * If we receive a TRY for an id that is lower the one		 * we would try, it is *NOT* for sure, that the remote		 * node has missed a TRY. This can happen if an outgoing		 * TRY is delayed at the remote node.		 */#ifdef DIST_GAP_REPORT		printf ("distGapInput: received TRY for `%s'/%d from node %ld\n",				pDistPktGapTry->tryName, pDistPktGapTry->tryId, distNodeIdSrc);#endif		msgQDistGrpDbLock();		/*		 * Test for conflicts. Try to find id and name in local database.		 * If found, ask for GLOBAL state.		 */		pGrpFoundById = msgQDistGrpLclFindById (pDistPktGapTry->tryId);		if (pGrpFoundById)			{			grpState = msgQDistGrpLclGetState (pGrpFoundById);#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: group id %d already in %s use\n",					pDistPktGapTry->tryId,					(grpState == DIST_GRP_STATE_GLOBAL) ? "global" : "local");#endif			if (grpState == DIST_GRP_STATE_GLOBAL)				{				/*				 * Someone sends a TRY for an id, already confirmed				 * by GAP. Give him a reject.				 */				DIST_PKT_GAP_REJECT	*pDistPktGapReject;				msgQDistGrpDbUnlock();#ifdef DIST_GAP_REPORT				printf ("distGapInput:TRY: group id already in use; reject\n");#endif				pDistPktGapReject = (DIST_PKT_GAP_REJECT *) &distPktGap;				pDistPktGapReject->rejectHdr.pktSubType =						DIST_PKT_TYPE_GAP_REJECT;				pDistPktGapReject->rejectId = htons (pDistPktGapReject->rejectId);				distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapReject,						sizeof (*pDistPktGapReject), WAIT_FOREVER,						DIST_GAP_PRIO);				break;				}			}		pGrpFoundByName = msgQDistGrpLclFindByName (pDistPktGapTry->tryName);		if (pGrpFoundByName)			{			grpState = msgQDistGrpLclGetState (pGrpFoundByName);#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: group name `%s' already in %s use\n",					pDistPktGapTry->tryName,					(grpState == DIST_GRP_STATE_GLOBAL) ? "global" : "local");#endif			if (grpState == DIST_GRP_STATE_GLOBAL)				{				DIST_PKT_GAP_SET	*pDistPktGapSet;				/*				 * Someone sends a TRY for a group that is in GLOBAL				 * state here.				 * This can happen, if				 * 1) someone did a TRY before receiving our				 *    SET (remote TRYs do not force creation of a				 *    database entry).				 * 2) a WAIT timed out and the state shifts to				 *    WAIT_TRY. In this case the remote node has				 *    missed the SET. Directly respond with SET.				 */				/*				 * Respond with SET.				 */				pDistPktGapSet = (DIST_PKT_GAP_SET *) &distPktGap;				pDistPktGapSet->setHdr.pktSubType = DIST_PKT_TYPE_GAP_SET;				pDistPktGapSet->setId = msgQDistGrpLclGetId (pGrpFoundByName);				msgQDistGrpDbUnlock();#ifdef DIST_GAP_REPORT				printf ("distGapInput/TRY: respond with SET `%s'/%d\n",						pDistPktGapSet->setName, pDistPktGapSet->setId);#endif				/* Convert setId (uint16) to network byte order */				pDistPktGapSet->setId = htons (pDistPktGapSet->setId);				distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapSet,						sizeof (*pDistPktGapSet), WAIT_FOREVER,						DIST_GAP_PRIO);				break;				}			}		else			{			DIST_GRP_DB_NODE	*pDistGrp;			/*			 * Create DB entry for new group.			 */			pDistGrp = msgQDistGrpLclCreate (pDistPktGapTry->tryName,					pDistPktGapTry->tryId, DIST_GRP_STATE_REMOTE_TRY);			if (pDistGrp == NULL)				{				/*				 * We cannot create a new node in the group database.				 * This is a fatal error.				 */				distPanic ("distGapInput:TRY: creation of new node failed\n");				}			/* only temporary, creator may change */			msgQDistGrpLclSetCreator (pDistGrp, distNodeIdSrc);			pDistGrp->pGrpDbGapNode = NULL;			}		/*		 * If there is a local group with the same name as currently		 * tried, it is not in GLOBAL state. We have checked this		 * before.		 */		if (pGrpFoundById == NULL && pGrpFoundByName == NULL)			{			DIST_PKT_GAP_OK	*pDistPktGapOk;			/*			 * No conflicts. Neither group id nor group name			 * are used in the local database.			 */			distGrpIdNext++;			msgQDistGrpDbUnlock();			/*			 * Respond with OK.			 */#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: neither id nor name used; respond OK\n");#endif			pDistPktGapOk = (DIST_PKT_GAP_OK *) &distPktGap;			pDistPktGapOk->okHdr.pktSubType = DIST_PKT_TYPE_GAP_OK;			/* Convert okId (uint16) to network byte order */			pDistPktGapOk->okId = htons (pDistPktGapOk->okId);			distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapOk,					sizeof (*pDistPktGapOk), WAIT_FOREVER, DIST_GAP_PRIO);			break;			}		if (pGrpFoundById == pGrpFoundByName)			{			/*			 * No conflict. There is already an object that			 * exactly matches the remote one.			 */			DIST_PKT_GAP_OK	*pDistPktGapOk = (DIST_PKT_GAP_OK *) &distPktGap;			msgQDistGrpDbUnlock();			/*			 * Respond with OK.			 */#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: id and name match; respond OK\n");#endif			pDistPktGapOk->okHdr.pktSubType = DIST_PKT_TYPE_GAP_OK;			/* Convert okId (uint16) to network byte order */            pDistPktGapOk->okId = htons (pDistPktGapOk->okId);			distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapOk,					sizeof (*pDistPktGapOk), WAIT_FOREVER, DIST_GAP_PRIO);			break;			}		/*		 * There is a conflict. Compare node ids to solve the conflict.		 * This is kind of a game: the one with the higher node id wins.		 */		if (distNodeLocalGetId() < distNodeIdSrc)			{			DIST_PKT_GAP_OK *pDistPktGapOk;			/*			 * We have lost. Do a local cleanup and send OK.			 */			distGrpIdNext++;#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: we have lost, trying %d\n",					pDistPktGapTry->tryId);#endif			if (pGrpFoundByName)				{				/*				 * Someone else is trying to create the same group, but has				 * a different group id. We have lost, so let us wait until				 * we receive a SET.				 */				/*				 * Remove linked list of outstanding responses.				 */				distGapOutstandUnlink (pGrpFoundByName->pGrpDbGapNode);				/*				 * Set WAIT state.				 */				msgQDistGrpLclSetState (pGrpFoundByName, DIST_GRP_STATE_WAIT);				pGrpFoundByName->pGrpDbGapNode->gapTimeout = DIST_GAP_WAIT_TIMO;				msgQDistGrpDbUnlock ();				}			else				{				/*				 * Someone else is trying to create a group with an				 * id, that was also proposed by us. We have lost,				 * so forget about the id and try another one.				 */								/*				 * Cleanup and reinitialize the GAP structure.				 */				distGapOutstandUnlink (pGrpFoundById->pGrpDbGapNode);				distGapOutstandLink (pGrpFoundById->pGrpDbGapNode);				pGrpFoundById->pGrpDbGapNode->gapTimeout = DIST_GAP_TRY_TIMO;				pGrpFoundById->pGrpDbGapNode->gapRetries = 1;				/*				 * Get a new id and reset state.				 */				msgQDistGrpLclSetId (pGrpFoundByName, distGrpIdNext++);				msgQDistGrpLclSetState (pGrpFoundByName,						DIST_GRP_STATE_LOCAL_TRY);				msgQDistGrpDbUnlock();				/*				 * Have a different TRY.				 */				distGapTry (DIST_IF_BROADCAST_ADDR, pGrpFoundByName);				}#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: respond with OK\n");#endif			pDistPktGapOk = (DIST_PKT_GAP_OK *) &distPktGap;			pDistPktGapOk->okHdr.pktSubType = DIST_PKT_TYPE_GAP_OK;			/* Convert okId (uint16) to network byte order */            pDistPktGapOk->okId = htons (pDistPktGapOk->okId);			distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapOk,					sizeof (*pDistPktGapOk), WAIT_FOREVER, DIST_GAP_PRIO);			}		else			{			/*			 * We won.			 */#ifdef DIST_GAP_REPORT			printf ("distGapInput/TRY: we have won, trying %d\n",					pDistPktGapTry->tryId);#endif			msgQDistGrpDbUnlock();			if (pGrpFoundByName)				{				/*				 * Someone is trying to create the same group, we				 * are trying, with a different group id. We won				 * the game, ask him to wait (ASK_WAIT).				 */				DIST_PKT_GAP_ASK_WAIT	*pDistPktGapAskWait;#ifdef DIST_GAP_REPORT				printf ("distGapInput/TRY: respond with ASK_WAIT\n");#endif				pDistPktGapAskWait = (DIST_PKT_GAP_ASK_WAIT *) &distPktGap;				pDistPktGapAskWait->askWaitHdr.pktSubType =						DIST_PKT_TYPE_GAP_ASK_WAIT;				/* Convert askWaitId (uint16) to network byte order */            	pDistPktGapAskWait->askWaitId = htons (pDistPktGapAskWait->askWaitId);				distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapAskWait,						sizeof (*pDistPktGapAskWait), WAIT_FOREVER,						DIST_GAP_PRIO);				}			else				{				/*				 * Someone is trying to create a group with an				 * id, already in use by us. We won the game, so				 * give him a REJECT.				 */				DIST_PKT_GAP_REJECT	*pDistPktGapReject;#ifdef DIST_GAP_REPORT				printf ("distGapInput/TRY: respond with REJECT\n");#endif				pDistPktGapReject = (DIST_PKT_GAP_REJECT *) &distPktGap;				pDistPktGapReject->rejectHdr.pktSubType =						DIST_PKT_TYPE_GAP_REJECT;				/* Convert rejectId (uint16) to network byte order */                pDistPktGapReject->rejectId = htons (pDistPktGapReject->rejectId);				distNetSend(distNodeIdSrc, (DIST_PKT *) pDistPktGapReject,						sizeof (*pDistPktGapReject), WAIT_FOREVER,						DIST_GAP_PRIO);				}			}		break;		}	/*	 * We have received an OK in response to an earlier TRY.	 */	case DIST_PKT_TYPE_GAP_OK:		{		DIST_PKT_GAP_OK		*pDistPktGapOk = (DIST_PKT_GAP_OK *) &distPktGap;		DIST_GRP_DB_NODE	*pDistGrp;		BOOL				more;		/* Convert okId (uint16) to host order */		pDistPktGapOk->okId = ntohs (pDistPktGapOk->okId);		#ifdef DIST_GAP_REPORT		printf ("distGapInput: received OK for `%s'/%d from node %ld\n",				pDistPktGapOk->okName, pDistPktGapOk->okId, distNodeIdSrc);#endif		msgQDistGrpDbLock();		/*		 * Try to find the confirmed id.		 */		pDistGrp = msgQDistGrpLclFindById (pDistPktGapOk->okId);		if (pDistGrp == NULL ||			msgQDistGrpLclGetState (pDistGrp) == DIST_GRP_STATE_GLOBAL)			{			/*			 * This is an OK for an id, that			 * 1) does not exist anymore (due to earlier REJECTs):			 *    This means, someone sent us a REJECT. As a			 *    consequence of this, we destoyed the local entry			 *    for this group and tried again with a new id.			 * 2) was confirmed by GAP earlier (group is in GLOBAL state).			 *			 * All responses to the old group id go here and will be ignored.			 */			msgQDistGrpDbUnlock();			break;			}		distGapLock();		/*		 * Update list of outstanding responses.		 */		more = distGapOutstandOk(pDistGrp->pGrpDbGapNode, distNodeIdSrc);		distGapUnlock();		if (more == FALSE)			{			msgQDistGrpLclSetState (pDistGrp, DIST_GRP_STATE_GLOBAL);			msgQDistGrpLclSetCreator (pDistGrp, distNodeLocalGetId());			msgQDistGrpDbUnlock();			distGapPh1Done (pDistGrp);			break;			}		msgQDistGrpDbUnlock();		break;		}	/*	 * We have received a REJECT.	 * Someone else is trying to create another group with an	 * id, that was also proposed by us. It seams, we have

⌨️ 快捷键说明

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