if (aclp->userp == userp) {
if (aclp->tgtLifetime && aclp->tgtLifetime <= osi_Time()) {
/* ticket expired */
- osi_QRemove((osi_queue_t **) &cm_data.aclLRUp, &aclp->q);
+ osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
CleanupACLEnt(aclp);
/* move to the tail of the LRU queue */
cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
/* move to the head of the LRU queue */
- osi_QRemove((osi_queue_t **) &cm_data.aclLRUp, &aclp->q);
+ osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
osi_QAddH((osi_queue_t **) &cm_data.aclLRUp,
(osi_queue_t **) &cm_data.aclLRUEndp,
&aclp->q);
aclp = cm_data.aclLRUEndp;
cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
- osi_QRemove((osi_queue_t **) &cm_data.aclLRUp, &aclp->q);
+ osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
if (aclp->backp && scp != aclp->backp) {
ascp = aclp->backp;
{
if (scp == cm_data.scacheLRULastp)
cm_data.scacheLRULastp = (cm_scache_t *) osi_QPrev(&scp->q);
- osi_QRemove((osi_queue_t **) &cm_data.scacheLRUFirstp, &scp->q);
+ osi_QRemoveHT((osi_queue_t **) &cm_data.scacheLRUFirstp, (osi_queue_t **) &cm_data.scacheLRULastp, &scp->q);
osi_QAdd((osi_queue_t **) &cm_data.scacheLRUFirstp, &scp->q);
if (!cm_data.scacheLRULastp)
cm_data.scacheLRULastp = scp;
if (scp->fileLocksT == q)
scp->fileLocksT = osi_QPrev(q);
- osi_QRemove(&scp->fileLocksH,q);
+ osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, q);
if (IS_LOCK_CLIENTONLY(fileLock)) {
scp->clientLocks--;
lock_ObtainWrite(&cm_scacheLock);
if (scp->fileLocksT == q)
scp->fileLocksT = osi_QPrev(q);
- osi_QRemove(&scp->fileLocksH, q);
+ osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, q);
/*
* Don't delete it here; let the daemon delete it, to simplify
lock_ObtainWrite(&cm_scacheLock);
if (scp->fileLocksT == &oldFileLock->fileq)
scp->fileLocksT = osi_QPrev(&oldFileLock->fileq);
- osi_QRemove(&scp->fileLocksH, &oldFileLock->fileq);
+ osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, &oldFileLock->fileq);
lock_ReleaseWrite(&cm_scacheLock);
} else if (code == 0 && IS_LOCK_WAITLOCK(oldFileLock)) {
scp->serverLock = newLock;
osi_LogPrint @58
osi_LogSaveString @59
osi_InitPanic @60
- osi_InitTraceOption @61
+ osi_InitTraceOption @61
osi_LogEvent0 @62
osi_LogEvent @63
- osi_HexifyString @64
+ osi_HexifyString @64
+ osi_QRemoveHT @65
void osi_QRemove(osi_queue_t **headpp, osi_queue_t *eltp)
{
- osi_queue_t *np; /* next dude */
-
- np = eltp->nextp; /* useful for both paths */
+ osi_queue_t *np = eltp->nextp; /* next dude */
+ osi_queue_t *pp = eltp->prevp; /* prev dude */
+
+ if (eltp == *headpp) {
+ /* we're the first element in the list */
+ *headpp = np;
+ if (np)
+ np->prevp = NULL;
+ }
+ else {
+ pp->nextp = np;
+ if (np)
+ np->prevp = pp;
+ }
+ eltp->prevp = NULL;
+ eltp->nextp = NULL;
+}
- if (eltp == *headpp) {
- /* we're the first element in the list */
- *headpp = np;
- if (np) np->prevp = NULL;
- }
- else {
- eltp->prevp->nextp = np;
- if (np) np->prevp = eltp->prevp;
- }
+void osi_QRemoveHT(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
+{
+ osi_queue_t *np = eltp->nextp; /* next dude */
+ osi_queue_t *pp = eltp->prevp; /* prev dude */
+
+ if (eltp == *headpp && eltp == *tailpp)
+ {
+ *headpp = *tailpp = NULL;
+ }
+ else if (eltp == *headpp) {
+ /* we're the first element in the list */
+ *headpp = np;
+ if (np)
+ np->prevp = NULL;
+ }
+ else if (eltp == *tailpp) {
+ /* we're the last element in the list */
+ *tailpp = pp;
+ if (pp)
+ pp->nextp = NULL;
+ }
+ else {
+ if (pp)
+ pp->nextp = np;
+ if (np)
+ np->prevp = pp;
+ }
+ eltp->prevp = NULL;
+ eltp->nextp = NULL;
}
void osi_InitQueue(void)
*/
extern void osi_QRemove(osi_queue_t **headpp, osi_queue_t *eltp);
+/* remove an element from a queue with both head and tail pointers;
+ * takes address of head and tail lists, and element to remove as parameters.
+ */
+extern void osi_QRemoveHT(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp);
+
/* initialize the queue package */
extern void osi_InitQueue(void);
* should be ignored.
*/
static osi_sleepInfo_t *osi_sleepers[OSI_SLEEPHASHSIZE];
+static osi_sleepInfo_t *osi_sleepersEnd[OSI_SLEEPHASHSIZE];
/* allocate space for lock operations */
osi_lockOps_t *osi_lockOps[OSI_NLOCKTYPES];
if (ap->states & OSI_SLEEPINFO_INHASH) {
ap->states &= ~OSI_SLEEPINFO_INHASH;
idx = osi_SLEEPHASH(ap->value);
- osi_QRemove((osi_queue_t **) &osi_sleepers[idx], &ap->q);
+ osi_QRemoveHT((osi_queue_t **) &osi_sleepers[idx], (osi_queue_t **) &osi_sleepersEnd[idx], &ap->q);
}
if (ap->states & OSI_SLEEPINFO_DELETED) {
for(i=0;i<OSI_SLEEPHASHSIZE; i++) {
InitializeCriticalSection(&osi_critSec[i]);
osi_sleepers[i] = (osi_sleepInfo_t *) NULL;
+ osi_sleepersEnd[i] = (osi_sleepInfo_t *) NULL;
}
/* free list CS */
void osi_TWait(osi_turnstile_t *turnp, int waitFor, void *patchp, CRITICAL_SECTION *releasep)
{
- osi_sleepInfo_t *sp;
- unsigned int code;
+ osi_sleepInfo_t *sp;
+ unsigned int code;
- sp = TlsGetValue(osi_SleepSlot);
- if (sp == NULL) {
- sp = osi_AllocSleepInfo();
- TlsSetValue(osi_SleepSlot, sp);
- }
- else
- sp->states = 0;
- sp->refCount = 0;
- sp->waitFor = waitFor;
- sp->value = (LONG_PTR) patchp;
- osi_QAdd((osi_queue_t **) &turnp->firstp, &sp->q);
- if (!turnp->lastp) turnp->lastp = sp;
- LeaveCriticalSection(releasep);
+ sp = TlsGetValue(osi_SleepSlot);
+ if (sp == NULL) {
+ sp = osi_AllocSleepInfo();
+ TlsSetValue(osi_SleepSlot, sp);
+ }
+ else {
+ sp->states = 0;
+ }
+ sp->refCount = 0;
+ sp->waitFor = waitFor;
+ sp->value = (LONG_PTR) patchp;
+ osi_QAddT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
+ if (!turnp->lastp)
+ turnp->lastp = sp;
+ LeaveCriticalSection(releasep);
/* now wait for the signal */
while(1) {
{
osi_sleepInfo_t *sp;
- if (!turnp->lastp) return;
+ if (!turnp->lastp)
+ return;
sp = turnp->lastp;
turnp->lastp = (osi_sleepInfo_t *) osi_QPrev(&sp->q);
- osi_QRemove((osi_queue_t **) &turnp->firstp, &sp->q);
+ osi_QRemoveHT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
sp->states |= OSI_SLEEPINFO_SIGNALLED;
ReleaseSemaphore(sp->sema, 1, (long *) 0);
}
while(sp = turnp->lastp) {
turnp->lastp = (osi_sleepInfo_t *) osi_QPrev(&sp->q);
- osi_QRemove((osi_queue_t **) &turnp->firstp, &sp->q);
+ osi_QRemoveHT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
sp->states |= OSI_SLEEPINFO_SIGNALLED;
ReleaseSemaphore(sp->sema, 1, (long *) 0);
} /* while someone's still asleep */
* the crit sec.
*/
turnp->lastp = (osi_sleepInfo_t *) osi_QPrev(&tsp->q);
- osi_QRemove((osi_queue_t **) &turnp->firstp, &tsp->q);
+ osi_QRemoveHT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &tsp->q);
/* do the patching required for lock obtaining */
if (tsp->waitFor & OSI_SLEEPINFO_W4WRITE) {
sp = osi_AllocSleepInfo();
TlsSetValue(osi_SleepSlot, sp);
}
- else
+ else {
sp->states = 0;
+ }
sp->refCount = 0;
sp->value = sleepValue;
idx = osi_SLEEPHASH(sleepValue);
csp = &osi_critSec[idx];
EnterCriticalSection(csp);
- osi_QAdd((osi_queue_t **) &osi_sleepers[idx], &sp->q);
+ osi_QAddT((osi_queue_t **) &osi_sleepers[idx], (osi_queue_t **) &osi_sleepersEnd[idx], &sp->q);
sp->states |= OSI_SLEEPINFO_INHASH;
LeaveCriticalSection(releasep);
LeaveCriticalSection(csp);