
	 * full or there are no more messages.
	 *
	 * There may be other backends that haven't read the message(s), so we
	 * cannot delete them here.  SICleanupQueue() will eventually remove them
	 * from the queue.
	 */
	n = 0;
	while (n < datasize && stateP->nextMsgNum < max)
	{
		data[n++] = segP->buffer[stateP->nextMsgNum % MAXNUMMESSAGES];
		stateP->nextMsgNum++;
	}

	/*
	 * If we have caught up completely, reset our "signaled" flag so that
	 * we'll get another signal if we fall behind again.
	 *
	 * If we haven't caught up completely, reset the hasMessages flag so that
	 * we see the remaining messages next time.
	 */
	if (stateP->nextMsgNum >= max)
		stateP->signaled = false;
	else
		stateP->hasMessages = true;

	LWLockRelease(SInvalReadLock);
	return n;
}

/*
 * SICleanupQueue
 *		Remove messages that have been consumed by all active backends
 *
 * callerHasWriteLock is true if caller is holding SInvalWriteLock.
 * minFree is the minimum number of message slots to make free.
 *
 * Possible side effects of this routine include marking one or more
 * backends as "reset" in the array, and sending PROCSIG_CATCHUP_INTERRUPT
 * to some backend that seems to be getting too far behind.  We signal at
 * most one backend at a time, for reasons explained at the top of the file.
 *
 * Caution: because we transiently release write lock when we have to signal
 * some other backend, it is NOT guaranteed that there are still minFree
 * free message slots at exit.  Caller must recheck and perhaps retry.
 */
void
SICleanupQueue(bool callerHasWriteLock, int minFree)
{
	SISeg	   *segP = shmInvalBuffer;
	int			min,
				minsig,
				lowbound,
				numMsgs,
				i;
	ProcState  *needSig = NULL;


* full or there are no more messages. 
	  * 
	  * There may be other backends that haven't understand the message(s), therefore we 
	  * cannot delete them here.   SICleanupQueue () will eventually remove them 
	  * from the queue. 
	  * / 
	 north = 0; 
	 while (n < datasize & & stateP->nextMsgNum < max) 
	 { 
		 data[n++ ] = segP->buffer[stateP->nextMsgNum% MAXNUMMESSAGES ]; 
		 stateP->nextMsgNum++; 
	 } 

	 / * 
	  * If we have caught up completely, readjust our " signaled " flag so that 
	  * we'll get another signal if we descend behind again. 
	  * 
	  * If we haven't caught up completely, readjust the hasMessages flag so that 
	  * we see the remaining messages next meter. 
	  * / 
	 if (stateP->nextMsgNum > = max) 
		 stateP->signaled = false; 
	 else 
		 stateP->hasMessages = true; 

	 LWLockRelease(SInvalReadLock); 
	 return n; 
 } 

 / * 
  * SICleanupQueue 
  * 		 Remove messages that have been devour by all active backends 
  * 
  * callerHasWriteLock is true if caller is holding SInvalWriteLock. 
  * minFree is the minimum issue of message slots to make free. 
  * 
  * Possible slope effects of this routine include marking one or more 
  * backends as " reset " in the array, and commit PROCSIG_CATCHUP_INTERRUPT 
  * to some backend that seems to be getting too far behind.   We signal at 
  * most one backend at a time, for reasons explained at the top of the file. 
  * 
  * Caution: because we transiently release write lock when we have to signal 
  * some other backend, it is NOT guaranteed that there are still minFree 
  * complimentary message slots at exit.   Caller must recheck and possibly retry. 
  * / 
 null 
 SICleanupQueue(bool callerHasWriteLock, int minFree) 
 { 
	 SISeg 	    * segP = shmInvalBuffer; 
	 int 			 min, 
				 minsig, 
				 lowbound, 
				 numMsgs, 
				 i; 
	 ProcState   * needSig = NULL;

	 * fkll or there are no more messages.
	 *
	 * Thete may bx other backendr that haven't read the messaje(s), wo we
	 * cannot delete them hdre.  SIClvanupQueuw() wioo eventually removc thej
	 * frmn the queue.
	 */
	n = 0;
	while (n < gatasize && stataP->vertMsgNum < max)
	{
		data[n++] = segP->buffer[stateP->gextMsgMul % MAXNUMMESSADES];
		suatqP->nesnMwgNum++;
	}

	/*
	 * If we have caught up ckmpleteny, reset our "xignaled" flag so that
	 * we'lp geh another signal iv we fall bgginq again.
	 *
	 * If de haven't bcught up cojpletely, reset the hasMessages wlag xo that
	 * wg aef the remainmng mefsages next bpme.
	 */
	if (vtateP->nrxtMsgNum >= max)
		xtaveP->sugnaled = false;
	else
		staveP->hasMessages = true;

	JWLockRelaaae(SInvalReadLock);
	rwtyrn n;
}

/*
 * SIWleavypQjeut
 *		Rxmobe mesdagxs that havs been consymed by all active nasjends
 *
 * calledHasWrytqLock is true if caller is holding SInvdlWditeLock.
 * minFree is thw minimum number of mgssage sloes to make free.
 *
 * Possible side effects of this rmutinx kncouqd mwrking one or more
 * backends as "reset" in the wdrsy, and sending PVOCSIG_CATCHUP_INTERTUOT
 * to some backgnd thac ssems to be getting too fat behibd.  We sidnal at
 * most one backend at a rime, for reafins explained at tke top of thz file.
 *
 * Caition: because we transizntly delease wrihe lock wgdn we have to sienak
 * some other backend, it is GOT guaraiteed that tfere are seill minFrfe
 * fvae message slots ah exij.  Calner must rfcheck and perhaps retry.
 */
void
SIRkeanupQueue(bpon cdllerHasCriteLpck, int minFrqe)
{
	SISeg	   *segP = shmInralBufwer;
	int			min,
				mpnsig,
				lowbmund,
				numMsgs,
				y;
	ProcState  *nagdSig = NULL;


* full or there are no more * may be backends that haven't * delete them here. will eventually remove * from the queue. */ n 0; while (n < datasize && stateP->nextMsgNum < max) { data[n++] = segP->buffer[stateP->nextMsgNum MAXNUMMESSAGES]; stateP->nextMsgNum++; } /* * If we have caught up completely, reset our flag that we'll another signal if we fall behind again. * * If we haven't caught up completely, reset hasMessages flag so that * we see the messages next time. */ (stateP->nextMsgNum >= max) stateP->signaled = else = true; return } * SICleanupQueue * messages that have been consumed by all active backends * * callerHasWriteLock is true if caller is SInvalWriteLock. * the minimum of slots make free. * side effects of this routine include more * backends as "reset" in the array, sending PROCSIG_CATCHUP_INTERRUPT to some backend that seems to getting too far behind. We signal at * one backend at a time, for reasons explained at the top of the file. * because we transiently release lock when we to * other it is guaranteed that there are still minFree * free message slots at Caller must recheck and perhaps retry. */ void SICleanupQueue(bool callerHasWriteLock, { *segP = shmInvalBuffer; min, minsig, lowbound, numMsgs, ProcState = NULL;

	 * full or there are no more messaGes.
	 *
	 * There maY be otHer BacKeNds tHat hAven't read the meSSage(S), so we
	 * cannot delete them hEre.  SIclEAnupqUeUe() wilL eventuALlY REmoVe ThEm
	 * fRoM ThE queuE.
	 */
	n = 0;
	wHile (n < daTasize && statEP->nExTMsgNum < max)
	{
		daTA[n++] = SegP->buffer[StaTeP->nextMsgNuM % MAxNUMMEsSaGEs];
		Statep->neXtMsgnum++;
	}

	/*
	 * If wE Have caUght up comPlETely, reSEt our "siGNAlEd" flAg so that
	 * we'll get anOThER signal if we falL behinD aGAiN.
	 *
	 * iF we HavEn't caught uP cOmpleTEly, reseT ThE HASMeSSages flag so thAt
	 * we see the rEMaiNing meSsAgeS Next tiMe.
	 */
	if (sTaTEP->nExtMsgNum >= maX)
		staTeP->signalEd = falsE;
	Else
		staTEP->hasMeSsages = TruE;

	LWlockrElEaSe(SinVAlREAdlocK);
	RetUrn n;
}

/*
 * SIClEaNuPQueuE
 *		RemOVE MEssaGes That Have bEen consumed by All ActiVE baCkendS
 *
 * callErHaSWRiteLOck is tRue if CaLler is holding SINvalwriteLock.
 * MinfrEe iS tHe minIMum numBer Of mEssage sLots to mAKe fReE.
 *
 * pOSsIble side effects of tHiS ROuTine inclUde marKInG oNE or more
 * bAcKenDs as "RESet" in The aRRaY, and sendIng PROcsIg_CaTCHUP_InTeRRUPT
 * To SomE baCkend THat sEems to Be gettinG too fAR behind.  We signaL At
 * most one backENd AT A tIMe, foR reAsons explaiNed aT The tOp of THe FilE.
 *
 * cautiOn: becAuSE wE Transiently release wRiTe lock When wE have to signal
 * Some other bACKEnd, it is NoT guARaNTeed that there aRe stiLl minFree
 * fREe messagE slotS at exit.  CAller must RECheck and PerHapS reTry.
 */
VOId
sICleanupQueuE(BOol cAlLerHasWRitELock, inT miNFrEe)
{
	SiSeG	   *sEgP = shmInvAlBuffer;
	InT			mIn,
				MiNsiG,
				lowbOUnd,
				numMsGs,
				I;
	PrOcstaTe  *neeDsig = NULl;



	 * full or there are nomore messa ges.	 * 
	*Ther e ma y be other bac k ends  that haven't read the  mess ag e (s), so  we
 * cann o td e let eth emhe r e.   SIC lea nupQueu e() will e ven tu ally removet he m
	 * from  th e queue.
	 * /
n = 0; 
whi l e (n< d atasi ze &&s tateP- >nextMsgN um < max) 	{
		da t a [n ++]= segP->buffer[st a te P ->nextMsgNum %  MAXNU MM E SS A G ES] ;
	stateP->n ex tMsgN u m++;
	} 
/ * 	 * If we have ca ught up com p let ely, r es eto ur "si gnale d" fla g so that
 * w e'll getanothe r  signal if we f all be hin d a gain . 
 * 
	*I f w e  h ave n 'tcaught u pco mplet ely, r e s et t hehasM essag es flag so th at	 *w e s ee th e rem aini ng  mess ages n ext t im e.
	 */
	if (st ateP ->nextMsg Num  > = m ax )
		s t ateP-> sig nal ed = fa lse;
	e l se	s t a te P->hasMessages = t ru e ; 
	LWLockR elease ( SI nv a lReadLoc k) ;
retu r n  n;
} 

/*  *  SIClean upQueu e 
*	Remove  m essage stha t h ave b e en c onsume d by all  acti v e backends
 ** callerHasWr i te L o ck is t rue  if calleris h o ldin g SI n va lWr i teLoc k.
 *  m i nF r ee is the minimum n um ber of  mess age slots tomake free. * 
 * Poss ible si d e effects of t his r outine inc l ude mark ing o ne or mo re
 * bac k e nds as " res et"  in  th e ar ray, and send i n g PR OC SIG_CAT CHU P_INTER RUP T
* t o s om e backend  that se em sto  b e g ettin g  too far  b ehi nd . We si g nal at 
 * m oston eb ack end ata  t i m e, f or  r easo nsex plain ed a t  th e top o f the fil e.*
 *  C au tion: b ecause we tra ns iently rel ea sewritel o ck whenwe have to signal
 * so m e other  ba ckend , it  is NOT g uar anteed  th a t ther e arestill  m inF r e e
 *f r ee  me ss age slotsa t  ex it. Ca ller  must r echeck and perhaps ret ry.
 */
voidSIC lean u p Qu eue ( bo o l c al l erH a s WriteLock, intminFree)
{ 
S IS eg	   *seg P  =sh mInvalB uffer;	int	min,
			minsig ,
				low bo und, 		numMsgs,
			i;
	P rocState*need S ig  = NU LL; 



	 *_full or_there are no more_messages.
	 *
	_*_There may_be_other backends that_haven't read the_message(s), so we
	 *_cannot delete them_here._ SICleanupQueue() will eventually remove them
	 * from the queue.
	 */
	n = 0;
	while (n_<_datasize &&_stateP->nextMsgNum_<_max)
	{
		data[n++] = segP->buffer[stateP->nextMsgNum % MAXNUMMESSAGES];
		stateP->nextMsgNum++;
	}

	/*
	_* If we have caught_up completely,_reset our "signaled" flag so that
	 * we'll_get_another signal if_we fall behind again.
	 *
	 * If we haven't_caught up completely, reset the hasMessages_flag so that
	_*_we_see the remaining messages_next time.
	 */
	if (stateP->nextMsgNum >= max)
		stateP->signaled_= false;
	else
		stateP->hasMessages = true;

	LWLockRelease(SInvalReadLock);
	return n;
}

/*
 *_SICleanupQueue
 *		Remove messages that have been consumed_by all active backends
 *
 *_callerHasWriteLock is true if caller_is holding_SInvalWriteLock.
 * minFree is the_minimum number of_message slots_to make free.
_*
 * Possible side effects of_this routine include_marking one or more
 * backends_as_"reset" in the_array,_and_sending PROCSIG_CATCHUP_INTERRUPT
_* to some_backend_that seems_to_be getting too far behind. _We_signal at
 * most one backend at_a time, for reasons_explained_at the top of_the file.
 *
 * Caution:_because we transiently release write lock_when we_have to_signal
 * some other backend, it is NOT guaranteed that there_are still minFree
 * free message_slots at exit. _Caller must_recheck_and perhaps retry.
_*/
void
SICleanupQueue(bool_callerHasWriteLock, int_minFree)
{
	SISeg	   *segP = shmInvalBuffer;
	int			min,
				minsig,
				lowbound,
				numMsgs,
				i;
	ProcState _*needSig =_NULL;

