prot_msg.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 282 行

C
282
字号
# ifndef lintstatic char *sccsid = "@(#)prot_msg.c	4.1	(ULTRIX)	7/2/90";# endif not lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************//**//* *	Modification history: *	~~~~~~~~~~~~~~~~~~~~ * *	revision			comments *	--------	----------------------------------------------- * *	01-Jun-89	Fred Glover *			Update for nfssrc 4.0 * *	18-Jan-88	fries *			Added Header and Copyright notice. * *	 *//* prot_msg.c * consists of all routines which handle msg passing */#include "prot_lock.h"#include "prot_time.h"extern int debug;extern int grace_period;extern int msg_len;extern remote_result res_working;char *xmalloc();msg_entry *klm_msg;	/* ptr last msg to klm in msg queue */msg_entry *msg_q;	/* head of msg queue *//* * retransmitted search through msg_queue to determine if "a" is  * retransmission of a previously received msg; * it returns the addr of the msg entry if "a" is found * otherwise, it returns NULL */msg_entry *retransmitted(a, proc)	reclock *a;	int proc;{	msg_entry *msgp;	msgp = msg_q;	while (msgp != NULL) {		if (same_lock(msgp->req, a) || simi_lock(msgp->req, a)) {			/* 5 is the constant diff between rpc calls and msg passing */			if ((msgp->proc == NLM_LOCK_RECLAIM &&			(proc == KLM_LOCK || proc == NLM_LOCK_MSG))		 || msgp->proc == proc + 5 || msgp->proc == proc) 				return(msgp);		}		msgp = msgp->nxt;	}	return(NULL);}/* * match response's cookie with msg req * either return msgp or NULL if not found */msg_entry *	search_msg(resp)	remote_result *resp;{	msg_entry *msgp;	reclock *req;	msgp = msg_q;	while (msgp != NULL) {		req = msgp->req;		if (obj_cmp(&req->cookie, &resp->cookie))			return(msgp);		msgp = msgp->nxt;	}	return(NULL);}/* * add a to msg queue; called from nlm_call: when rpc call is succ and reply is needed * proc is needed for sending back reply later * if case of error, NULL is returned; * otherwise, the msg entry is returned */msg_entry *queue(a, proc)	reclock *a;	int proc;{	msg_entry *msgp;	if ((msgp = (msg_entry *) xmalloc(msg_len)) == NULL)		return(NULL);	bzero((char *) msgp, msg_len);	msgp->req = a;	msgp->proc = proc;	msgp->t.exp = 1;	/* insert msg into msg queue */	if (msg_q == NULL) {		msgp->nxt = msgp->prev = NULL;		msg_q = msgp;		/* turn on alarm only when there are msgs in msg queue */		if (grace_period == 0)			(void) alarm(LM_TIMEOUT);	}	else {		msgp->nxt = msg_q;		msgp->prev = NULL;		msg_q->prev = msgp;		msg_q = msgp;	}	if ( proc != NLM_GRANTED_MSG && proc != NLM_LOCK_RECLAIM)		klm_msg = msgp;			/* record last msg to klm*/	return(msgp);}/* * dequeue remove msg from msg_queue; * and deallocate space obtained  from malloc * lockreq is release only if a->rel == 1; */dequeue(msgp)	msg_entry *msgp;{	/*	 * First, delete msg from msg queue since dequeue(),	 * release_le() and dequeue_reclock() are recursive.	 */	if (msgp->prev != NULL)		msgp->prev->nxt = msgp->nxt;	else		msg_q = msgp->nxt;	if (msgp->nxt != NULL)		msgp->nxt->prev = msgp->prev;	if (msgp->req != NULL)		release_le(msgp->req);	if (msgp->reply != NULL)		release_res(msgp->reply);	bzero((char *) msgp, sizeof (*msgp));	free((char *) msgp);}/* * Find a reclock and dequeue it.  But do not actually free reclock here. */voiddequeue_reclock(a)	reclock *a;{	msg_entry *msgp;	msgp = msg_q;	while (msgp != NULL) {		if (a == msgp->req) {			msgp->req = NULL;  /* don't free here; caller does it */			dequeue(msgp);			dequeue_reclock(a); /* is there another ? */			return;		}		msgp = msgp->nxt;	}}/* * if resp is not NULL, add reply to msg_entyr and reply if msg is last req; * otherwise, reply working */add_reply(msgp, resp )	msg_entry *msgp;	remote_result *resp;{	if ( resp != NULL) {		msgp->t.curr = 0;		/* reset timer counter to record old msg */		msgp->reply = resp; 		if (klm_msg == msgp) { /* reply immed */ 			klm_reply(msgp->proc, resp); 			klm_msg = NULL;			/* prevent timer routine reply "working" to already replied req */			if (resp->lstat != blocking) 				dequeue(msgp); 		}        	}	else /* res == NULL, used by xtimer */ 		if (klm_msg == msgp) {			if (debug)				printf("xtimer reply to (%x): ", msgp->req);			klm_reply(msgp->proc, &res_working);		}}/* * signal handler: * wake up periodically to check retransmiting status and reply to last req */xtimer(){	msg_entry *msgp, *next;	if (debug)		printf("\nalarm! enter xtimer:\n");	if (grace_period > 0) {		/* reduce the remaining grace period */		grace_period--;		if (grace_period == 0) {			if (debug)				printf("**********end of grace period\n");			/* remove proc == klm_xxx in msg queue */			next = msg_q;			while ((msgp = next) != NULL) {				next = msgp->nxt;				if (msgp->proc == KLM_LOCK || msgp->proc == KLM_UNLOCK				 || msgp->proc == KLM_TEST || msgp->proc == KLM_CANCEL) {					if (debug)						printf("remove grace period msg (%x) from msg queue\n", msgp);					dequeue(msgp);				}			}		}	}	next = msg_q;	while ((msgp = next) != NULL) {		next = msgp->nxt;		if (msgp->reply == NULL) { /* check for retransimssion */			if (msgp->proc != KLM_LOCK) { /* KLM_LOCK is for local blocked locks */				if (msgp->t.exp == msgp->t.curr) {/* retransmit */					if (debug)						printf("xtimer retransmit: ");					(void) nlm_call(msgp->proc, msgp->req, 1);					msgp->t.curr = 0;					msgp->t.exp = 2 * msgp->t.exp;	/* double timeout period */					if (msgp->t.exp > MAX_LM_TIMEOUT_COUNT) {						msgp->t.exp = MAX_LM_TIMEOUT_COUNT;					}				}				else 	/* increment current count */					msgp->t.curr++;			}		}		else { /* check if reply is sitting there too long */			if (msgp->reply->lstat != blocking) {						if (msgp->t.curr > OLDMSG) /* discard this msg */					dequeue(msgp);				else					msgp->t.curr++;			}		}	}	/* send back working reply for last req received in klm */	if (klm_msg != NULL) {			if (debug)			printf("klm_msg = %x\n", klm_msg->req);		add_reply(klm_msg, NULL);	}	else if (debug)		printf("klm_msg == NULL\n");	if (grace_period != 0 || msg_q != NULL)		(void) alarm(LM_TIMEOUT);}

⌨️ 快捷键说明

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