/******************************************************************************* * 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; }
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; }
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; }
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); } }
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) */ }
/*! * 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); }
/* 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; }
/*! * 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; }