/* call with cell write-locked and mutex held */ void cm_AddCellToIDHashTable(cm_cell_t *cellp) { int i; lock_AssertWrite(&cm_cellLock); lock_AssertMutex(&cellp->mx); if (cellp->flags & CM_CELLFLAG_IN_IDHASH) return; i = CM_CELL_ID_HASH(cellp->cellID); cellp->idNextp = cm_data.cellIDHashTablep[i]; cm_data.cellIDHashTablep[i] = cellp; _InterlockedOr(&cellp->flags, CM_CELLFLAG_IN_IDHASH); }
/* call with volume write-locked and mutex held */ void cm_AddCellToNameHashTable(cm_cell_t *cellp) { int i; lock_AssertWrite(&cm_cellLock); lock_AssertMutex(&cellp->mx); if (cellp->flags & CM_CELLFLAG_IN_NAMEHASH) return; i = CM_CELL_NAME_HASH(cellp->name); cellp->nameNextp = cm_data.cellNameHashTablep[i]; cm_data.cellNameHashTablep[i] = cellp; _InterlockedOr(&cellp->flags, CM_CELLFLAG_IN_NAMEHASH); }
/*! \brief Begin an RPC operation While generally we receive RPC requests one at a time, we have to protect against receiving multiple requests in parallel since there's nothing really preventing that from happening. This should be called before calling any of the smb_RPC_*() functions. If the return value is non-zero, it should be considered unsafe to call any smb_RPC_*() function. Each successful call to smb_RPC_BeginOp() should be coupled with a call to smb_RPC_EndOp(). \note Should be called with rpcp->fidp->mx locked. */ afs_int32 smb_RPC_BeginOp(smb_rpc_t * rpcp) { if (rpcp == NULL) return CM_ERROR_INVAL; osi_assertx(rpcp->fidp, "No fidp assigned to smb_rpc_t"); lock_AssertMutex(&rpcp->fidp->mx); while (rpcp->fidp->flags & SMB_FID_RPC_INCALL) { osi_SleepM((LONG_PTR) rpcp, &rpcp->fidp->mx); lock_ObtainMutex(&rpcp->fidp->mx); } rpcp->fidp->flags |= SMB_FID_RPC_INCALL; return 0; }
unsigned long main_Scan1(unsigned long parm) { while (1) { osi_Log0(main_logp, "scan1"); /* check to see if we're done */ lock_ObtainRead(&main_doneRWLock); lock_AssertRead(&main_doneRWLock); if (done >= 2) break; lock_ReleaseRead(&main_doneRWLock); /* check state for consistency */ lock_ObtainMutex(&main_aMutex); lock_AssertMutex(&main_aMutex); Sleep(0); lock_ObtainRead(&main_bRWLock); Sleep(0); osi_assert(a+b == 100); lock_ReleaseRead(&main_bRWLock); Sleep(0); lock_ReleaseMutex(&main_aMutex); /* get a read lock here to test people getting stuck on RW lock alone */ lock_ObtainRead(&main_bRWLock); Sleep(0); lock_ReleaseRead(&main_bRWLock); s1Loops++; osi_Log2(main_logp, "scan1 done %d %d", s1Loops, 2); } lock_ReleaseRead(&main_doneRWLock); lock_ObtainWrite(&main_doneRWLock); lock_AssertWrite(&main_doneRWLock); done++; lock_ReleaseWrite(&main_doneRWLock); return 0; }
/* call with cell write-locked and mutex held */ void cm_RemoveCellFromIDHashTable(cm_cell_t *cellp) { cm_cell_t **lcellpp; cm_cell_t *tcellp; int i; lock_AssertWrite(&cm_cellLock); lock_AssertMutex(&cellp->mx); if (cellp->flags & CM_CELLFLAG_IN_IDHASH) { /* hash it out first */ i = CM_CELL_ID_HASH(cellp->cellID); for (lcellpp = &cm_data.cellIDHashTablep[i], tcellp = cm_data.cellIDHashTablep[i]; tcellp; lcellpp = &tcellp->idNextp, tcellp = tcellp->idNextp) { if (tcellp == cellp) { *lcellpp = cellp->idNextp; _InterlockedAnd(&cellp->flags, ~CM_CELLFLAG_IN_IDHASH); cellp->idNextp = NULL; break; } } } }
/* call with cell write-locked and mutex held */ void cm_RemoveCellFromNameHashTable(cm_cell_t *cellp) { cm_cell_t **lcellpp; cm_cell_t *tcellp; int i; lock_AssertWrite(&cm_cellLock); lock_AssertMutex(&cellp->mx); if (cellp->flags & CM_CELLFLAG_IN_NAMEHASH) { /* hash it out first */ i = CM_CELL_NAME_HASH(cellp->name); for (lcellpp = &cm_data.cellNameHashTablep[i], tcellp = cm_data.cellNameHashTablep[i]; tcellp; lcellpp = &tcellp->nameNextp, tcellp = tcellp->nameNextp) { if (tcellp == cellp) { *lcellpp = cellp->nameNextp; cellp->flags &= ~CM_CELLFLAG_IN_NAMEHASH; cellp->nameNextp = NULL; break; } } } }