示例#1
0
/*******************************************************************************
* Procedure:    RFU_GetRxChar
* Purpose:      xxxx
* Passed:       xxxx
*   
* Returned:     nothing
* Globals:      none
*
* Date:         Author:             Comments:
*   2014-09-19  Neal Shurmantine    initial revision
*******************************************************************************/
bool RFU_GetRxChar(unsigned char *rslt)
{
    if (QEmpty(&RxQueue) == false ) {
        QRemove(rslt,&RxQueue);
        if (QEmpty(&RxQueue) == true) {
            OS_EventClear(ActiveEventHandle,ActiveEventBit);
        }
        return true;
    }
    return false;
}
示例#2
0
PCBptr deQ(Que *Q)
/* deQ returns the first member of the Q */
{
 PCBptr retval; /* return value */
 
 if(!QEmpty(Q))
  {
   retval = Q->front;
   Q->front = Q->front->next;
  }
 else retval = (PCBptr)0;
 
 if (QEmpty(Q))
  Q->rear = NULL;
 
 return retval;
}
示例#3
0
void enQ(PCBptr p, Que *Q)
/* enQ puts the PCB onto the end of the  Q */
{
 p->next = NULL;
 if (QEmpty(Q))
  Q->front = p;
 else
   Q->rear->next = p;
 Q->rear =  p;
}
示例#4
0
void KX_StateActuator::Activate(SG_DList& head)
{
	// sort the state actuators per object on the global list
	if (QEmpty())
	{
		InsertSelfActiveQList(m_stateActuatorHead, &m_gameobj->m_firstState);
		// add front to make sure it runs before other actuators
		head.AddFront(&m_stateActuatorHead);
	}
}
示例#5
0
static void
afs_DisconDiscardAllShadows(int squash, afs_ucred_t *acred)
{
   struct vcache *tvc;

   while (!QEmpty(&afs_disconShadow)) {
	tvc = QEntry(QNext(&afs_disconShadow), struct vcache, shadowq);

	/* Must release the dirty lock to be able to get a vcache lock */
	ReleaseWriteLock(&afs_disconDirtyLock);
	ObtainWriteLock(&tvc->lock, 706);

	if (squash)
	   afs_ResetVCache(tvc, acred, 0);

	afs_DeleteShadowDir(tvc);

	ReleaseWriteLock(&tvc->lock);
	ObtainWriteLock(&afs_disconDirtyLock, 709);
    }				/* while (tvc) */
}
示例#6
0
/*!
 * This function throws away the whole disconnected state, allowing
 * the cache manager to reconnect to a server if we get into a state
 * where reconiliation is impossible.
 *
 * \param acred
 *
 */
void
afs_DisconDiscardAll(afs_ucred_t *acred)
{
    struct vcache *tvc;

    ObtainWriteLock(&afs_disconDirtyLock, 717);
    while (!QEmpty(&afs_disconDirty)) {
	tvc = QEntry(QPrev(&afs_disconDirty), struct vcache, dirtyq);
	QRemove(&tvc->dirtyq);
	ReleaseWriteLock(&afs_disconDirtyLock);

	ObtainWriteLock(&tvc->lock, 718);
	afs_ResetVCache(tvc, acred, 0);
	tvc->f.truncPos = AFS_NOTRUNC;
	ReleaseWriteLock(&tvc->lock);
	ObtainWriteLock(&afs_disconDirtyLock, 719);
	afs_PutVCache(tvc);
    }

    afs_DisconDiscardAllShadows(1, acred);

    ReleaseWriteLock(&afs_disconDirtyLock);
}
示例#7
0
/* Because there are no real-time guarantees, and especially because a
 * thread may wait on a lock indefinitely, this routine has to be
 * careful that it doesn't get permanently out-of-date.  Important
 * assumption: this routine is only called from afs_Daemon, so there
 * can't be more than one instance of this running at any one time.
 * Presumes that basetime is never 0, and is always sane. 
 *
 * Before calling this routine, be sure that the first slot is pretty
 * empty.  This -20 is because the granularity of the checks in
 * afs_Daemon is pretty large, so I'd rather err on the side of safety
 * sometimes.  The fact that I only bump basetime by CBHTSLOTLEN-1
 * instead of the whole CBHTSLOTLEN is also for "safety".
 * Conceptually, it makes this clock run just a little faster than the
 * clock governing which slot a callback gets hashed into.  Both of these 
 * things make CheckCallbacks work a little harder than it would have to 
 * if I wanted to cut things finer.
 * Everything from the old first slot is carried over into the new first
 * slot.  Thus, if there were some things that ought to have been invalidated,
 * but weren't (say, if the server was down), they will be examined at every
 * opportunity thereafter.
 */
int
afs_BumpBase(void)
{
    afs_uint32 now;
    int didbump;
    u_int oldbase;

    ObtainWriteLock(&afs_xcbhash, 87);
    didbump = 0;
    now = osi_Time();
    while (basetime + (CBHTSLOTLEN - 20) <= now) {
	oldbase = base;
	basetime += CBHTSLOTLEN - 1;
	base = (base + 1) % CBHTSIZE;
	didbump++;
	if (!QEmpty(&(cbHashT[oldbase].head))) {
	    QCat(&(cbHashT[oldbase].head), &(cbHashT[base].head));
	}
    }
    ReleaseWriteLock(&afs_xcbhash);

    return didbump;
}
示例#8
0
/*!
 * All files that have been dirty before disconnection are going to
 * be replayed back to the server.
 *
 * \param areq Request from the user.
 * \param acred User credentials.
 *
 * \return If all files synchronized succesfully, return 0, otherwise
 * return error code
 *
 * \note For now, it's the request from the PDiscon pioctl.
 *
 */
int
afs_ResyncDisconFiles(struct vrequest *areq, afs_ucred_t *acred)
{
    struct afs_conn *tc;
    struct rx_connection *rxconn;
    struct vcache *tvc;
    struct AFSFetchStatus fstat;
    struct AFSCallBack callback;
    struct AFSVolSync tsync;
    int code = 0;
    afs_int32 start = 0;
    XSTATS_DECLS;
    /*AFS_STATCNT(afs_ResyncDisconFiles);*/

    ObtainWriteLock(&afs_disconDirtyLock, 707);

    while (!QEmpty(&afs_disconDirty)) {
	tvc = QEntry(QPrev(&afs_disconDirty), struct vcache, dirtyq);

	/* Can't lock tvc whilst holding the discon dirty lock */
	ReleaseWriteLock(&afs_disconDirtyLock);

	/* Get local write lock. */
	ObtainWriteLock(&tvc->lock, 705);

	if (tvc->f.ddirty_flags & VDisconRemove) {
	    /* Delete the file on the server and just move on
	     * to the next file. After all, it has been deleted
	     * we can't replay any other operation it.
	     */
	    code = afs_ProcessOpRemove(tvc, areq);
	    goto next_file;

	} else if (tvc->f.ddirty_flags & VDisconCreate) {
	    /* For newly created files, we don't need a server lock. */
	    code = afs_ProcessOpCreate(tvc, areq, acred);
	    if (code)
	    	goto next_file;

	    tvc->f.ddirty_flags &= ~VDisconCreate;
	    tvc->f.ddirty_flags |= VDisconCreated;
	}
#if 0
  	/* Get server write lock. */
  	do {
	    tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
  	    if (tc) {
	    	XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_SETLOCK);
  		RX_AFS_GUNLOCK();
  		code = RXAFS_SetLock(rxconn,
					(struct AFSFid *)&tvc->f.fid.Fid,
					LockWrite,
					&tsync);
		RX_AFS_GLOCK();
		XSTATS_END_TIME;
	   } else
		code = -1;

	} while (afs_Analyze(tc,
			     rxconn,
			     code,
			     &tvc->f.fid,
			     areq,
			     AFS_STATS_FS_RPCIDX_SETLOCK,
			     SHARED_LOCK,
			     NULL));

	if (code)
	    goto next_file;
#endif
	if (tvc->f.ddirty_flags & VDisconRename) {
	    /* If we're renaming the file, do so now */
	    code = afs_ProcessOpRename(tvc, areq);
	    if (code)
	    	goto unlock_srv_file;
	}

	/* Issue a FetchStatus to get info about DV and callbacks. */
	do {
	    tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
	    if (tc) {
	    	tvc->callback = tc->srvr->server;
		start = osi_Time();
		XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_FETCHSTATUS);
		RX_AFS_GUNLOCK();
		code = RXAFS_FetchStatus(rxconn,
				(struct AFSFid *)&tvc->f.fid.Fid,
				&fstat,
				&callback,
				&tsync);
		RX_AFS_GLOCK();
		XSTATS_END_TIME;
	    } else
		code = -1;

	} while (afs_Analyze(tc,
			     rxconn,
			     code,
			     &tvc->f.fid,
			     areq,
			     AFS_STATS_FS_RPCIDX_FETCHSTATUS,
			     SHARED_LOCK,
			     NULL));

	if (code) {
	    goto unlock_srv_file;
	}

	if ((dv_match(tvc, fstat) && (tvc->f.m.Date == fstat.ServerModTime)) ||
	    	(afs_ConflictPolicy == CLIENT_WINS) ||
		(tvc->f.ddirty_flags & VDisconCreated)) {
	    /*
	     * Send changes to the server if there's data version match, or
	     * client wins policy has been selected or file has been created
	     * but doesn't have it's the contents on to the server yet.
	     */
	   /*
	    * XXX: Checking server attr changes by timestamp might not the
	    * most elegant solution, but it's the most viable one that we could find.
	    */
	    afs_UpdateStatus(tvc, &tvc->f.fid, areq, &fstat, &callback, start);
	    code = afs_SendChanges(tvc, areq);

	} else if (afs_ConflictPolicy == SERVER_WINS) {
	    /* DV mismatch, apply collision resolution policy. */
	    /* Discard this files chunks and remove from current dir. */
	    afs_ResetVCache(tvc, acred, 0);
	    tvc->f.truncPos = AFS_NOTRUNC;
	} else {
	    /* printf("afs_ResyncDisconFiles: no resolution policy selected.\n"); */
	}		/* if DV match or client wins policy */

unlock_srv_file:
	/* Release server write lock. */
#if 0
	do {
	    tc = afs_Conn(&tvc->f.fid, areq, SHARED_LOCK, &rxconn);
	    if (tc) {
	    	XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK);
	    	RX_AFS_GUNLOCK();
		ucode = RXAFS_ReleaseLock(rxconn,
				(struct AFSFid *) &tvc->f.fid.Fid,
				&tsync);
		RX_AFS_GLOCK();
		XSTATS_END_TIME;
	    } else
		ucode = -1;
	} while (afs_Analyze(tc,
			     rxconn,
			     ucode,
			     &tvc->f.fid,
			     areq,
			     AFS_STATS_FS_RPCIDX_RELEASELOCK,
			     SHARED_LOCK,
			     NULL));
#endif
next_file:
	ObtainWriteLock(&afs_disconDirtyLock, 710);
	if (code == 0) {
	    /* Replayed successfully - pull the vcache from the
	     * disconnected list */
	    tvc->f.ddirty_flags = 0;
	    QRemove(&tvc->dirtyq);
	    afs_PutVCache(tvc);
	} else {
	    if (code == EAGAIN)	{
		/* Operation was deferred. Pull it from the current place in
		 * the list, and stick it at the end again */
		QRemove(&tvc->dirtyq);
	   	QAdd(&afs_disconDirty, &tvc->dirtyq);
	    } else {
		/* Failed - keep state as is, and let the user know we died */

    		ReleaseWriteLock(&tvc->lock);
		break;
	    }
	}

	/* Release local write lock. */
	ReleaseWriteLock(&tvc->lock);
    }			/* while (tvc) */

    if (code) {
        ReleaseWriteLock(&afs_disconDirtyLock);
	return code;
    }

    /* Dispose of all of the shadow directories */
    afs_DisconDiscardAllShadows(0, acred);

    ReleaseWriteLock(&afs_disconDirtyLock);
    return code;
}