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

📄 distgaplib.c

📁 vxworks操作系统的源代码 供研究学习
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * lost a remote comparison, so forget about the old group	 * id and try a new one.	 */	case DIST_PKT_TYPE_GAP_REJECT:		{		DIST_PKT_GAP_REJECT *pDistPktGapReject;		DIST_GRP_DB_NODE	*pDistGrp;		pDistPktGapReject = (DIST_PKT_GAP_REJECT *) &distPktGap;		/* Convert rejectId (uint16) to host order */		pDistPktGapReject->rejectId = ntohs (pDistPktGapReject->rejectId);		#ifdef DIST_GAP_REPORT		printf ("distGapInput: received REJECT for `%s'/%d from node %ld\n",				pDistPktGapReject->rejectName, pDistPktGapReject->rejectId,				distNodeIdSrc);#endif		msgQDistGrpDbLock();		pDistGrp = msgQDistGrpLclFindById (pDistPktGapReject->rejectId);		if (pDistGrp == NULL ||			msgQDistGrpLclGetState (pDistGrp) == DIST_GRP_STATE_GLOBAL)			{			/*			 * This is a REJECT 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;			}		/*		 * Cleanup and reinitialize the GAP structure.		 */		distGapOutstandUnlink (pDistGrp->pGrpDbGapNode);		distGapOutstandLink (pDistGrp->pGrpDbGapNode);		pDistGrp->pGrpDbGapNode->gapTimeout = DIST_GAP_TRY_TIMO;		pDistGrp->pGrpDbGapNode->gapRetries = 1;		/*		 * Get a new id and reset state.		 */		msgQDistGrpLclSetId (pDistGrp, distGrpIdNext++);		msgQDistGrpLclSetState (pDistGrp, DIST_GRP_STATE_LOCAL_TRY);		msgQDistGrpDbUnlock();		/*		 * Have a different TRY.		 */		distGapTry (DIST_IF_BROADCAST_ADDR, pDistGrp);		break;		}	/*	 * We received an ASK_WAIT. We have send a TRY before. Someone else	 * found a conflict, where it is trying to create the same group, but	 * with an alternate id. Since the other node has a higher node id	 * it asks us to wait for a SET.	 */	case DIST_PKT_TYPE_GAP_ASK_WAIT:		{		DIST_PKT_GAP_ASK_WAIT	*pDistPktGapAskWait;		DIST_GRP_DB_NODE		*pDistGrp;		pDistPktGapAskWait = (DIST_PKT_GAP_ASK_WAIT *) &distPktGap;		/* Convert askWaitId (uint16) to host byte order */		pDistPktGapAskWait->askWaitId = ntohs (pDistPktGapAskWait->askWaitId);#ifdef DIST_GAP_REPORT		printf ("distGapInput: received ASK_WAIT for `%s'/%d from node %ld\n",				pDistPktGapAskWait->askWaitName, pDistPktGapAskWait->askWaitId,				distNodeIdSrc);#endif		msgQDistGrpDbLock();		pDistGrp = msgQDistGrpLclFindByName (pDistPktGapAskWait->askWaitName);		if (pDistGrp == NULL ||			msgQDistGrpLclGetState (pDistGrp) == DIST_GRP_STATE_GLOBAL)			{			/*			 * This is an ASK_WAIT 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;			}		if (msgQDistGrpLclGetState (pDistGrp) != DIST_GRP_STATE_WAIT)			{			/*			 * Remove the list of outstanding responses. Do *NOT*			 * remove the GAP structure.			 */			distGapOutstandUnlink (pDistGrp->pGrpDbGapNode);			msgQDistGrpLclSetState (pDistGrp, DIST_GRP_STATE_WAIT);			pDistGrp->pGrpDbGapNode->gapTimeout = DIST_GAP_WAIT_TIMO;			}		msgQDistGrpDbUnlock();		break;		}	/*	 * We have received a SET. When receiving a SET, we already should	 * have received a TRY and responded to it with OK.	 */	case DIST_PKT_TYPE_GAP_SET:		{		DIST_PKT_GAP_SET	*pDistPktGapSet;		DIST_GRP_DB_NODE	*pGrpFoundById;		DIST_GRP_DB_NODE	*pGrpFoundByName;		DIST_GRP_DB_NODE	*pDistGrp;		pDistPktGapSet = (DIST_PKT_GAP_SET *) &distPktGap;		/* Convert setId (uint16) to host byte order */		pDistPktGapSet->setId = ntohs (pDistPktGapSet->setId);#ifdef DIST_GAP_REPORT		printf ("distGapInput: received SET for `%s'/%d from node %ld\n",				pDistPktGapSet->setName, pDistPktGapSet->setId, distNodeIdSrc);#endif		/*		 * Sanity check: Is this a SET from future?		 */		if (pDistPktGapSet->setId >= distGrpIdNext)			{			/*			 * There was no TRY for this SET! Just ignore this.			 */#ifdef DIST_DIAGNOSTIC			distLog ("distGapInput/SET: no TRY for SET\n");#endif			break;			}		msgQDistGrpDbLock();		pGrpFoundById = msgQDistGrpLclFindById (pDistPktGapSet->setId);		pGrpFoundByName = msgQDistGrpLclFindByName (pDistPktGapSet->setName);		if (pGrpFoundByName &&			(!pGrpFoundById || pGrpFoundById == pGrpFoundByName) &&			(msgQDistGrpLclGetState (pGrpFoundByName) != DIST_GRP_STATE_GLOBAL))			{			/*			 * When do we get here?			 * We were waiting for this one. An earlier TRY asked us to			 * wait. Here is the SET we waited for.			 */#ifdef DIST_GAP_REPORT			printf ("distGapInput/SET: got SET for existing nonglobal group");#endif			msgQDistGrpLclSetId (pGrpFoundByName, pDistPktGapSet->setId);			msgQDistGrpLclSetState (pGrpFoundByName, DIST_GRP_STATE_GLOBAL);			msgQDistGrpLclSetCreator (pGrpFoundByName, distNodeIdSrc);			if (pGrpFoundByName->pGrpDbGapNode)				{				distGapOutstandUnlink (pGrpFoundByName->pGrpDbGapNode);				semFlush (&pGrpFoundByName->pGrpDbGapNode->gapWaitFor);				}			msgQDistGrpDbUnlock();			break;			}		if (pGrpFoundById != pGrpFoundByName)			{			/*			 * Id or name are already in database but do not point			 * to the same object. This can happen, if we receive			 * multiple SETs.			 */			msgQDistGrpDbUnlock();#ifdef DIST_GAP_REPORT			printf ("distGapInput/SET: id or name already in database\n");#endif			break;			}		if (pGrpFoundById && pGrpFoundById == pGrpFoundByName)			{			/*			 * An exact copy of this object is already in the database.			 * Ignore state.			 */#ifdef DIST_GAP_REPORT			printf ("distGapInput/SET: `%s' (0x%lx) is already in database\n",				pDistPktGapSet->setName, (u_long) pDistPktGapSet->setId);#endif			msgQDistGrpLclSetState (pGrpFoundByName, DIST_GRP_STATE_GLOBAL);			msgQDistGrpLclSetCreator (pGrpFoundByName, distNodeIdSrc);			if (pGrpFoundByName->pGrpDbGapNode != NULL)				semFlush (&pGrpFoundByName->pGrpDbGapNode->gapWaitFor);			msgQDistGrpDbUnlock();			break;			}		/*		 * Neither id nor name are found in the database.		 * Create node in group database.		 */#ifdef DIST_GAP_REPORT		printf ("distGapInput/SET: creating local db entry `%s' (0x%lx)\n",				pDistPktGapSet->setName, (u_long) pDistPktGapSet->setId);#endif		pDistGrp = msgQDistGrpLclCreate (pDistPktGapSet->setName,				pDistPktGapSet->setId, DIST_GRP_STATE_GLOBAL);		msgQDistGrpLclSetCreator (pDistGrp, distNodeLocalGetId ());		if (pDistGrp == NULL)			{			/*			 * We have a SET from remote and cannot create a new			 * node in the group database. This is a fatal error.			 */			distPanic ("distGapInput:SET: creation of new node failed\n");			}		msgQDistGrpLclSetCreator (pDistGrp, distNodeIdSrc);		msgQDistGrpDbUnlock();				break;		}	/*	 * This type of telegram is unknown.	 */	default:		{		/*		 * When we get here, the packet is already acknowledged.		 * But this makes no difference since an unknown type of		 * telegram is a fatal error. Let's panic!		 */#ifdef DIST_DIAGNOSTIC		distPanic ("distGapInput: unknown type of telegram\n");#endif		}	}	return (DIST_GAP_STATUS_OK);	}#ifdef DIST_GAP_TASK/********************************************************************************* distGapTimerTask - Timeout management task*** NOMANUAL*/LOCAL void distGapTimerTask ()	{	while (1)		{		distGapTimer ();		taskDelay (DIST_GAP_MGR_WAKEUP_TICKS);		}	}/********************************************************************************* distGapTimer - Timeout management** The job of the distGapTimer() is to go through the list of active* GAPs to see if a GAP has timed out.** NOMANUAL*/LOCAL void distGapTimer ()	{	DIST_GAP_NODE *pGapNode;	distGapLock();	/*	 * Run through list of open GAPs.	 */	pGapNode = (DIST_GAP_NODE *) DLL_FIRST (&gapInProgress);	while (pGapNode != NULL)	{	DIST_GAP_RESPONSE	*pDistGapResponse =			(DIST_GAP_RESPONSE *) SLL_FIRST (&pGapNode->gapOutstand);	switch (msgQDistGrpLclGetState (pGapNode->pGapGrp))		{		case DIST_GRP_STATE_LOCAL_TRY:	/* try initiated by us */		case DIST_GRP_STATE_WAIT_TRY:	/* retry after wait */		{		/*		 * This GAP is open and we are still trying.		 */		if (pGapNode->gapTimeout == 0)			{			/*			 * GAP has timed out. Lookup the missing nodes.			 */			DIST_GAP_RESPONSE	*pDistGapResponsePrev;			while (pDistGapResponse != NULL)			{			if (distNodeGetState (pDistGapResponse->pGapResponseNode) ==					DIST_NODE_STATE_OPERATIONAL)				{				/*				 * According to our local database the node is OPERATIONAL.				 * Check the number of retries.				 */				DIST_NODE_ID	distNodeIdMissing =						pDistGapResponse->pGapResponseNode->nodeId;				if (pGapNode->gapRetries++ > DIST_GAP_MAX_RETRIES)					{					/*					 * The number of retries is within the limit.					 * Send a unicast TRY with a higher timeout to the					 * missing node.					 */					pGapNode->gapTimeout =							pGapNode->gapRetries * DIST_GAP_TRY_TIMO;					distGapTry (distNodeIdMissing, pGapNode->pGapGrp);					}				else					{					/*					 * We have exceeded the limit of max retries.					 * The remote node seams to be dead. Tell the node					 * database about our assumption.					 */					(void) distNodeCrashed (distNodeIdMissing);					distGapOutstandDel (pGapNode, pDistGapResponse,							pDistGapResponsePrev);					}				}			else				{				/*				 * Node has died, while we were waiting for a response.				 * Dying is something like agreeing.				 */				distGapOutstandDel (pGapNode, pDistGapResponse,						pDistGapResponsePrev);				}			pDistGapResponsePrev = pDistGapResponse;			pDistGapResponse = (DIST_GAP_RESPONSE *)					SLL_NEXT (pDistGapResponse);			}	/* while (pDistGapResponse != NULL) */			}		pGapNode->gapTimeout--;		break;		}		case DIST_GRP_STATE_WAIT:		{		/*		 * Someone told us to wait.		 */		if (pGapNode->gapTimeout == 0)			{			/*			 * GAP timed out and we are still waiting for a SET. We will			 * return to try again, but we must not forget the WAITing			 * state we were in, since the missing SET might come in at			 * any time.			 */			DIST_GRP_DB_NODE	*pDistGrp;			/*			 * Reinitialize the GAP structure. Cleanup was done,			 * before entering WAITing state.			 */				distGapOutstandLink (pGapNode);			pDistGrp->pGrpDbGapNode->gapTimeout = DIST_GAP_TRY_TIMO;			pDistGrp->pGrpDbGapNode->gapRetries = 1;			/*			 * Get a new id and reset state.			 */			pDistGrp = pGapNode->pGapGrp;						msgQDistGrpLclSetId (pDistGrp, distGrpIdNext++);			msgQDistGrpLclSetState (pDistGrp, DIST_GRP_STATE_WAIT_TRY);			/*			 * Have another TRY with a different id.			 */			distGapTry (DIST_IF_BROADCAST_ADDR, pDistGrp);			}		pGapNode->gapTimeout--;		break;		}		default:		{#ifdef DIST_DIAGNOSTIC			distLog ("distGapTimer: `%s' in unknown or unexpected state %d\n",					&pGapNode->pGapGrp->grpDbName,					pGapNode->pGapGrp->grpDbState);#endif		}		}	/* switch (state) */	pGapNode = (DIST_GAP_NODE *) DLL_NEXT (pGapNode);	}	/* while (pGapNode != NULL) */	distGapUnlock();	}#endif

⌨️ 快捷键说明

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