Exemple #1
0
/* must be called with sleep bucket locked.
 * Frees the structure if it has a 0 reference count (and removes it
 * from the hash bucket).  Otherwise, we simply mark the item
 * for deleting when the ref count hits zero.
 */
void osi_FreeSleepInfo(osi_sleepInfo_t *sp)
{
    LONG_PTR idx;

    if (sp->refCount > 0) {
	TlsSetValue(osi_SleepSlot, NULL);	/* don't reuse me */
	_InterlockedOr(&sp->states, OSI_SLEEPINFO_DELETED);
	return;
    }

    /* remove from hash if still there */
    if (sp->states & OSI_SLEEPINFO_INHASH) {
	idx = osi_SLEEPHASH(sp->value);
	osi_QRemoveHT((osi_queue_t **) &osi_sleepers[idx], (osi_queue_t **) &osi_sleepersEnd[idx], &sp->q);
	_InterlockedAnd(&sp->states, ~OSI_SLEEPINFO_INHASH);
    }

    if (sp->states & OSI_SLEEPINFO_DELETED) {
	EnterCriticalSection(&osi_sleepInfoAllocCS);
	sp->q.nextp = (osi_queue_t *) osi_sleepInfoFreeListp;
	osi_sleepInfoFreeListp = sp;
	_InterlockedAnd(&sp->states, ~OSI_SLEEPINFO_DELETED);
	InterlockedIncrement(&osi_sleepInfoCount);
	LeaveCriticalSection(&osi_sleepInfoAllocCS);
    }
}
Exemple #2
0
VOID
BtrReleaseSpinLock(
	IN PBTR_SPINLOCK Lock
	)
{	
	Lock->ThreadId = 0;
	_InterlockedAnd((volatile LONG *)&Lock->Acquired, 0);
}
void ResumeFromSuspension() {
    // This is meant to be called from the main thread only. 
    assert(g_SuspensionRequested && SuspensionCompleted());

    _InterlockedAnd(&g_SuspensionRequested, 0);
    if (!SetEvent(g_hResumeFromSuspension)) {
        exit(GetLastError());
    }
}
Exemple #4
0
unsigned
Atomic::AND(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_fetch_and_and(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
    return _InterlockedAnd(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
    return OSAtomicAnd32((uint32_t)value, (uint32_t *)&_value);
#else
# error This implementation should happen inline in the include file
#endif
}
Exemple #5
0
/* utility function to atomically (with respect to WakeSched)
 * release an atomic counter spin lock and sleep on an
 * address (value).
 * Called with no locks held.
 */
void osi_SleepSpin(LONG_PTR sleepValue, CRITICAL_SECTION *releasep)
{
    int code;
    osi_sleepInfo_t *sp;
    CRITICAL_SECTION *csp;

    sp = TlsGetValue(osi_SleepSlot);
    if (sp == NULL) {
	sp = osi_AllocSleepInfo();
	TlsSetValue(osi_SleepSlot, sp);
    }
    else {
	_InterlockedAnd(&sp->states, 0);
    }
    sp->waitFor = 0;
    sp->value = sleepValue;
    sp->tidp = NULL;
    sp->idx = osi_SLEEPHASH(sleepValue);
    csp = &osi_critSec[sp->idx];
    EnterCriticalSection(csp);
    osi_QAddT((osi_queue_t **) &osi_sleepers[sp->idx], (osi_queue_t **) &osi_sleepersEnd[sp->idx], &sp->q);
    _InterlockedOr(&sp->states, OSI_SLEEPINFO_INHASH);
    LeaveCriticalSection(csp);
    LeaveCriticalSection(releasep);
    InterlockedIncrement(&osi_totalSleeps);	/* stats */
    while(1) {
	/* wait */
	code = WaitForSingleObject(sp->sema,
				    /* timeout */ INFINITE);

	/* if the reason for the wakeup was that we were signalled,
	* break out, otherwise try again, since the semaphore count is
	* decreased only when we get WAIT_OBJECT_0 back.
	*/
	if (code == WAIT_OBJECT_0) break;
    }

    /* now clean up */
    EnterCriticalSection(csp);

    /* must be signalled */
    osi_assert(sp->states & OSI_SLEEPINFO_SIGNALLED);

    /* free the sleep structure, must be done under bucket lock
     * so that we can check reference count and serialize with
     * those who change it.
     */
    osi_FreeSleepInfo(sp);

    LeaveCriticalSection(csp);
}
Exemple #6
0
void osi_TWaitExt(osi_turnstile_t *turnp, int waitFor, void *patchp, DWORD *tidp, CRITICAL_SECTION *releasep, int prepend)
{
    osi_sleepInfo_t *sp;
    unsigned int code;

    sp = TlsGetValue(osi_SleepSlot);
    if (sp == NULL) {
	sp = osi_AllocSleepInfo();
	TlsSetValue(osi_SleepSlot, sp);
    }
    else {
	_InterlockedAnd(&sp->states, 0);
    }
    sp->waitFor = waitFor;
    sp->value = (LONG_PTR) patchp;
    sp->tidp = tidp;
    sp->idx = -1;
    if (prepend)
        osi_QAddH((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
    else
        osi_QAddT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
    LeaveCriticalSection(releasep);

    /* now wait for the signal */
    while(1) {
        /* wait */
        code = WaitForSingleObject(sp->sema,
                                    /* timeout */ INFINITE);

        /* if the reason for the wakeup was that we were signalled,
         * break out, otherwise try again, since the semaphore count is
         * decreased only when we get WAIT_OBJECT_0 back.
         */
        if (code == WAIT_OBJECT_0) break;
    }	/* while we're waiting */

    /* we're the only one who should be looking at or changing this
     * structure after it gets signalled.  Sema sp->sema isn't signalled
     * any longer after we're back from WaitForSingleObject, so we can
     * free this element directly.
     */
    osi_assert(sp->states & OSI_SLEEPINFO_SIGNALLED);

    osi_FreeSleepInfo(sp);

    /* reobtain, since caller commonly needs it */
    EnterCriticalSection(releasep);
}
// Locks all other processors and returns exclusivity pointer. This function
// should never be called before the last exclusivity is released.
_Use_decl_annotations_ EXTERN_C
void *ExclGainExclusivity()
{
    NT_ASSERT(InterlockedAdd(&g_ExclpNumberOfLockedProcessors, 0) == 0);
    _InterlockedAnd(&g_ExclpReleaseAllProcessors, 0);

    const auto numberOfProcessors = KeQueryActiveProcessorCount(nullptr);

    // Allocates DPCs for all processors.
    auto context = reinterpret_cast<ExclusivityContext *>(ExAllocatePoolWithTag(
        NonPagedPoolNx, sizeof(void *) + (numberOfProcessors * sizeof(KDPC)),
        EXCLP_POOL_TAG));
    if (!context)
    {
        return nullptr;
    }

    // Execute a lock DPC for all processors but this.
    context->OldIrql = KeRaiseIrqlToDpcLevel();
    const auto currentCpu = KeGetCurrentProcessorNumber();
    for (auto i = 0ul; i < numberOfProcessors; i++)
    {
        if (i == currentCpu)
        {
            continue;
        }

        // Queue a lock DPC.
        KeInitializeDpc(&context->Dpcs[i], ExclpRaiseIrqlAndWaitDpc, nullptr);
        KeSetTargetProcessorDpc(&context->Dpcs[i], static_cast<CCHAR>(i));
        KeInsertQueueDpc(&context->Dpcs[i], nullptr, nullptr);
    }

    // Wait until all other processors were halted.
    const auto needToBeLocked = numberOfProcessors - 1;
    while (_InterlockedCompareExchange(&g_ExclpNumberOfLockedProcessors,
        needToBeLocked, needToBeLocked) !=
        static_cast<LONG>(needToBeLocked))
    {
        KeStallExecutionProcessor(10);
    }
    return context;
}
Exemple #8
0
BOOL Condition::Wait(DWORD timeout)
{
// 参考程度の空き開始位置調査
// (正確な確認は、INIT_EVENT <-> WAIT_EVENT の CAS で)
	u_int	idx = get_ntz(_InterlockedExchangeAdd(&gEventMap, 0));
	u_int	self_bit = 0;
	if (idx >= MaxThreads) idx = 0;

	int	count = 0;
	while (count < MaxThreads) {
		if (InterlockedCompareExchange(&gEvents[idx].kind, WAIT_EVENT, INIT_EVENT) == INIT_EVENT) {
			self_bit = 1 << idx;
			_InterlockedAnd(&gEventMap, ~self_bit);
			break;
		}
		if (++idx == MaxThreads) idx = 0;
		count++;
	}
	if (count >= MaxThreads) {	// 通常はありえない
		MessageBox(0, "Detect too many wait threads", "TLib", MB_OK);
		return	FALSE;
	}
	Event	&event = gEvents[idx];

	if (event.hEvent == NULL) {
		event.hEvent = ::CreateEvent(0, FALSE, FALSE, NULL);
	}
	waitBits |= self_bit;

	UnLock();

	DWORD	status = ::WaitForSingleObject(event.hEvent, timeout);

	Lock();
	waitBits &= ~self_bit;
	InterlockedExchange(&event.kind, INIT_EVENT);
	_InterlockedOr(&gEventMap, self_bit);

	return	status == WAIT_TIMEOUT ? FALSE : TRUE;
}
Exemple #9
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;
	    }
	}
    }
}
Exemple #10
0
cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
{
    cm_cell_t *cp, *cp2;
    long code;
    char fullname[CELL_MAXNAMELEN]="";
    char linkedName[CELL_MAXNAMELEN]="";
    char name[CELL_MAXNAMELEN]="";
    int  hasWriteLock = 0;
    int  hasMutex = 0;
    afs_uint32 hash;
    cm_cell_rock_t rock;
    size_t len;

    if (namep == NULL || !namep[0] || !strcmp(namep,CM_IOCTL_FILENAME_NOSLASH))
        return NULL;

    /*
     * Strip off any trailing dots at the end of the cell name.
     * Failure to do so results in an undesireable alias as the
     * result of DNS AFSDB record lookups where a trailing dot
     * has special meaning.
     */
    strncpy(name, namep, CELL_MAXNAMELEN);
    for (len = strlen(namep); len > 0 && namep[len-1] == '.'; len--) {
        name[len-1] = '\0';
    }
    if (len == 0)
        return NULL;
    namep = name;

    hash = CM_CELL_NAME_HASH(namep);

    lock_ObtainRead(&cm_cellLock);
    for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) {
        if (cm_stricmp_utf8(namep, cp->name) == 0) {
            strncpy(fullname, cp->name, CELL_MAXNAMELEN);
            fullname[CELL_MAXNAMELEN-1] = '\0';
            break;
        }
    }

    if (!cp) {
        for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) {
            if (strnicmp(namep, cp->name, strlen(namep)) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }
    }

    if (cp) {
        lock_ReleaseRead(&cm_cellLock);
        cm_UpdateCell(cp, flags);
    } else if (flags & CM_FLAG_CREATE) {
        lock_ConvertRToW(&cm_cellLock);
        hasWriteLock = 1;

        /* when we dropped the lock the cell could have been added
         * to the list so check again while holding the write lock
         */
        for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) {
            if (cm_stricmp_utf8(namep, cp->name) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }

        if (cp)
            goto done;

        for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) {
            if (strnicmp(namep, cp->name, strlen(namep)) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }

        if (cp) {
            lock_ReleaseWrite(&cm_cellLock);
            lock_ObtainMutex(&cp->mx);
            lock_ObtainWrite(&cm_cellLock);
            cm_AddCellToNameHashTable(cp);
            cm_AddCellToIDHashTable(cp);
            lock_ReleaseMutex(&cp->mx);
            goto done;
        }

        if ( cm_data.freeCellsp != NULL ) {
            cp = cm_data.freeCellsp;
            cm_data.freeCellsp = cp->freeNextp;

            /*
             * The magic, cellID, and mx fields are already set.
             */
        } else {
            if ( cm_data.currentCells >= cm_data.maxCells )
                osi_panic("Exceeded Max Cells", __FILE__, __LINE__);

            /* don't increment currentCells until we know that we
             * are going to keep this entry
             */
            cp = &cm_data.cellBaseAddress[cm_data.currentCells];
            memset(cp, 0, sizeof(cm_cell_t));
            cp->magic = CM_CELL_MAGIC;

            /* the cellID cannot be 0 */
            cp->cellID = ++cm_data.currentCells;

            /* otherwise we found the cell, and so we're nearly done */
            lock_InitializeMutex(&cp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL);
        }

        lock_ReleaseWrite(&cm_cellLock);
        hasWriteLock = 0;

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellRegistry(1, namep, fullname, linkedName, cm_AddCellProc, &rock);
        if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
            code = cm_SearchCellFileEx(namep, fullname, linkedName, cm_AddCellProc, &rock);
        if (code) {
            osi_Log4(afsd_logp,"in cm_GetCell_gen cm_SearchCellFileEx(%s) returns code= %d fullname= %s linkedName= %s",
                      osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname),
                      osi_LogSaveString(afsd_logp,linkedName));

            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, &rock);
                if ( code ) {
                    osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
                             osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname));
                    lock_ObtainMutex(&cp->mx);
                    lock_ObtainWrite(&cm_cellLock);
                    hasWriteLock = 1;
                    cm_RemoveCellFromIDHashTable(cp);
                    cm_RemoveCellFromNameHashTable(cp);
                    lock_ReleaseMutex(&cp->mx);
                    cm_FreeCell(cp);
                    cp = NULL;
                    goto done;
                } else {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    hasMutex = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS);
                    _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID);
                    cp->timeout = time(0) + ttl;
                }
            }
            else
            {
                lock_ObtainMutex(&cp->mx);
                lock_ObtainWrite(&cm_cellLock);
                hasWriteLock = 1;
                cm_RemoveCellFromIDHashTable(cp);
                cm_RemoveCellFromNameHashTable(cp);
                lock_ReleaseMutex(&cp->mx);
                cm_FreeCell(cp);
                cp = NULL;
                goto done;
	    }
        } else {
            lock_ObtainMutex(&cp->mx);
            hasMutex = 1;
	    cp->timeout = time(0) + 7200;	/* two hour timeout */
	}

        /* we have now been given the fullname of the cell.  It may
         * be that we already have a cell with that name.  If so,
         * we should use it instead of completing the allocation
         * of a new cm_cell_t
         */
        lock_ObtainRead(&cm_cellLock);
        hash = CM_CELL_NAME_HASH(fullname);
        for (cp2 = cm_data.cellNameHashTablep[hash]; cp2; cp2=cp2->nameNextp) {
            if (cm_stricmp_utf8(fullname, cp2->name) == 0) {
                break;
            }
        }

        if (cp2) {
            if (!hasMutex) {
                lock_ObtainMutex(&cp->mx);
                hasMutex = 1;
            }
            lock_ConvertRToW(&cm_cellLock);
            hasWriteLock = 1;
            cm_RemoveCellFromIDHashTable(cp);
            cm_RemoveCellFromNameHashTable(cp);
            lock_ReleaseMutex(&cp->mx);
            hasMutex = 0;
            cm_FreeCell(cp);
            cp = cp2;
            goto done;
        }
        lock_ReleaseRead(&cm_cellLock);

        /* randomise among those vlservers having the same rank*/
        cm_RandomizeServer(&cp->vlServersp);

        if (!hasMutex)
            lock_ObtainMutex(&cp->mx);

        /* copy in name */
        strncpy(cp->name, fullname, CELL_MAXNAMELEN);
        cp->name[CELL_MAXNAMELEN-1] = '\0';

        strncpy(cp->linkedName, linkedName, CELL_MAXNAMELEN);
        cp->linkedName[CELL_MAXNAMELEN-1] = '\0';

        lock_ObtainWrite(&cm_cellLock);
        hasWriteLock = 1;
        cm_AddCellToNameHashTable(cp);
        cm_AddCellToIDHashTable(cp);
        lock_ReleaseMutex(&cp->mx);
        hasMutex = 0;

        /* append cell to global list */
        if (cm_data.allCellsp == NULL) {
            cm_data.allCellsp = cp;
        } else {
            for (cp2 = cm_data.allCellsp; cp2->allNextp; cp2=cp2->allNextp)
                ;
            cp2->allNextp = cp;
        }
        cp->allNextp = NULL;

    } else {
        lock_ReleaseRead(&cm_cellLock);
    }
  done:
    if (hasMutex && cp)
        lock_ReleaseMutex(&cp->mx);
    if (hasWriteLock)
        lock_ReleaseWrite(&cm_cellLock);

    /* fullname is not valid if cp == NULL */
    if (newnamep) {
        if (cp) {
            strncpy(newnamep, fullname, CELL_MAXNAMELEN);
            newnamep[CELL_MAXNAMELEN-1]='\0';
        } else {
            newnamep[0] = '\0';
        }
    }

    if (cp && cp->linkedName[0]) {
        cm_cell_t * linkedCellp = NULL;

        if (!strcmp(cp->name, cp->linkedName)) {
            cp->linkedName[0] = '\0';
        } else if (!(flags & CM_FLAG_NOMOUNTCHASE)) {
            linkedCellp = cm_GetCell(cp->linkedName, CM_FLAG_CREATE|CM_FLAG_NOPROBE|CM_FLAG_NOMOUNTCHASE);

            lock_ObtainWrite(&cm_cellLock);
            if (!linkedCellp ||
                (linkedCellp->linkedName[0] && strcmp(cp->name, linkedCellp->linkedName))) {
                cp->linkedName[0] = '\0';
            } else {
                strncpy(linkedCellp->linkedName, cp->name, CELL_MAXNAMELEN);
                linkedCellp->linkedName[CELL_MAXNAMELEN-1]='\0';
            }
            lock_ReleaseWrite(&cm_cellLock);
        }
    }
    return cp;
}
Exemple #11
0
LONG test_InterlockedAnd(LONG volatile *value, LONG mask) {
  return _InterlockedAnd(value, mask);
}
Exemple #12
0
void
cm_PingServer(cm_server_t *tsp)
{
    long code;
    int wasDown = 0;
    cm_conn_t *connp;
    struct rx_connection * rxconnp;
    Capabilities caps = {0, 0};
    char hoststr[16];
    cm_req_t req;

    lock_ObtainMutex(&tsp->mx);
    if (InterlockedIncrement(&tsp->pingCount) > 1) {
	tsp->waitCount++;
	osi_SleepM((LONG_PTR)tsp, &tsp->mx);
	lock_ObtainMutex(&tsp->mx);
	InterlockedDecrement(&tsp->pingCount);
	if (--tsp->waitCount > 0)
	    osi_Wakeup((LONG_PTR)tsp);
	lock_ReleaseMutex(&tsp->mx);
	return;
    }
    wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
    afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
    lock_ReleaseMutex(&tsp->mx);

    if (cm_noIPAddr > 0)
	code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &connp);
    else
	code = RX_CALL_DEAD;	/* No network */
    if (code == 0) {
	/* now call the appropriate ping call.  Drop the timeout if
	* the server is known to be down, so that we don't waste a
	* lot of time retiming out down servers.
	*/

	osi_Log4(afsd_logp, "cm_PingServer server %s (%s) was %s with caps 0x%x",
		  osi_LogSaveString(afsd_logp, hoststr),
		  tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
		  wasDown ? "down" : "up",
		  tsp->capabilities);

        rxconnp = cm_GetRxConn(connp);
	if (wasDown)
	    rx_SetConnHardDeadTime(rxconnp, 10);
	if (tsp->type == CM_SERVER_VLDB) {
	    code = VL_ProbeServer(rxconnp);
	}
	else {
	    /* file server */
	    code = RXAFS_GetCapabilities(rxconnp, &caps);
	}
	if (wasDown)
	    rx_SetConnHardDeadTime(rxconnp, HardDeadtimeout);
        rx_PutConnection(rxconnp);
	cm_PutConn(connp);
    }	/* got an unauthenticated connection to this server */

    lock_ObtainMutex(&tsp->mx);
    if (code >= 0 || code == RXGEN_OPCODE) {
	/* mark server as up */
	_InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
        tsp->downTime = 0;

	/* we currently handle 32-bits of capabilities */
	if (code != RXGEN_OPCODE && caps.Capabilities_len > 0) {
	    tsp->capabilities = caps.Capabilities_val[0];
	    xdr_free((xdrproc_t) xdr_Capabilities, &caps);
	    caps.Capabilities_len = 0;
	    caps.Capabilities_val = 0;
	} else {
	    tsp->capabilities = 0;
	}

	osi_Log3(afsd_logp, "cm_PingServer server %s (%s) is up with caps 0x%x",
		  osi_LogSaveString(afsd_logp, hoststr),
		  tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
		  tsp->capabilities);

        /* Now update the volume status if necessary */
        if (wasDown) {
            cm_server_vols_t * tsrvp;
            cm_volume_t * volp;
            int i;

            for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) {
                for (i=0; i<NUM_SERVER_VOLS; i++) {
                    if (tsrvp->ids[i] != 0) {
                        cm_InitReq(&req);

                        lock_ReleaseMutex(&tsp->mx);
                        code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
                                                &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
                        lock_ObtainMutex(&tsp->mx);
                        if (code == 0) {
                            cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
                            cm_PutVolume(volp);
                        }
                    }
                }
            }
            cm_RankServer(tsp);
        }
    } else {
	cm_MarkServerDown(tsp, code, wasDown);

	osi_Log3(afsd_logp, "cm_PingServer server %s (%s) is down with caps 0x%x",
		  osi_LogSaveString(afsd_logp, hoststr),
		  tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
		  tsp->capabilities);
    }

    InterlockedDecrement(&tsp->pingCount);
    if (tsp->waitCount > 0)
	osi_Wakeup((LONG_PTR)tsp);
    lock_ReleaseMutex(&tsp->mx);
}
	/* _Atomic_fetch_and_4 */
_Uint4_t _Fetch_and_seq_cst_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
	{	/* and _Value with *_Tgt atomically with
			sequentially consistent memory order */
	_Value = _InterlockedAnd((volatile long *)_Tgt, _Value);
	return (_Value);
	}
Exemple #14
0
Int32 KInterlockedAnd(Int32 volatile * var, Int32 add)
{
    return _InterlockedAnd((volatile long*)var, add);
}
Exemple #15
0
long
cm_CreateCellWithInfo( char * cellname,
                       char * linked_cellname,
                       unsigned short vlport,
                       afs_uint32 host_count,
                       char *hostname[],
                       afs_uint32 flags)
{
    afs_uint32 code = 0;
    cm_cell_rock_t rock;
    struct hostent *thp;
    struct sockaddr_in vlSockAddr;
    afs_uint32 i, j;

    rock.cellp = cm_GetCell(cellname, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
    rock.flags = 0;

    cm_FreeServerList(&rock.cellp->vlServersp, CM_FREESERVERLIST_DELETE);

    if (!(flags & CM_CELLFLAG_DNS)) {
        for (i = 0; i < host_count; i++) {
            thp = gethostbyname(hostname[i]);
            if (thp) {
                int foundAddr = 0;
                for (j=0 ; thp->h_addr_list[j]; j++) {
                    if (thp->h_addrtype != AF_INET)
                        continue;
                    memcpy(&vlSockAddr.sin_addr.s_addr,
                           thp->h_addr_list[j],
                           sizeof(long));
                    vlSockAddr.sin_port = htons(vlport ? vlport : 7003);
                    vlSockAddr.sin_family = AF_INET;
                    cm_AddCellProc(&rock, &vlSockAddr, hostname[i], CM_FLAG_NOPROBE);
                }
            }
        }
        lock_ObtainMutex(&rock.cellp->mx);
        _InterlockedAnd(&rock.cellp->flags, ~CM_CELLFLAG_DNS);
    } else if (cm_dnsEnabled) {
        int ttl;

        code = cm_SearchCellByDNS(rock.cellp->name, NULL, &ttl, cm_AddCellProc, &rock);
        lock_ObtainMutex(&rock.cellp->mx);
        if (code == 0) {   /* got cell from DNS */
            _InterlockedOr(&rock.cellp->flags, CM_CELLFLAG_DNS);
            rock.cellp->timeout = time(0) + ttl;
#ifdef DEBUG
            fprintf(stderr, "cell %s: ttl=%d\n", rock.cellp->name, ttl);
#endif
        }
    } else {
        lock_ObtainMutex(&rock.cellp->mx);
        rock.cellp->flags &= ~CM_CELLFLAG_DNS;
    }
    _InterlockedOr(&rock.cellp->flags, CM_CELLFLAG_VLSERVER_INVALID);
    StringCbCopy(rock.cellp->linkedName, CELL_MAXNAMELEN, linked_cellname);
    lock_ReleaseMutex(&rock.cellp->mx);

    if (rock.cellp->vlServersp)
        cm_RandomizeServer(&rock.cellp->vlServersp);

    return code;
}
Exemple #16
0
/* if it's from DNS, see if it has expired
 * and check to make sure we have a valid set of volume servers
 * this function must not be called with a lock on cm_cellLock
 */
cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags)
{
    long code = 0;
    cm_cell_rock_t rock;
    afs_uint32 mxheld = 0;

    if (cp == NULL)
        return NULL;

    lock_ObtainMutex(&cp->mx);
    mxheld = 1;

#ifdef AFS_FREELANCE_CLIENT
    if (cp->flags & CM_CELLFLAG_FREELANCE) {
        lock_ReleaseMutex(&cp->mx);
        return cp;
    }
#endif

    if (cm_IsServerListEmpty(cp->vlServersp) ||
        (time(0) > cp->timeout) ||
        (cm_dnsEnabled &&
         (cp->flags & CM_CELLFLAG_DNS) &&
         ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID))))
    {
        lock_ReleaseMutex(&cp->mx);
        mxheld = 0;

        /* must empty cp->vlServersp */
        if (cp->vlServersp)
            cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellRegistry(1, cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
            code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code == 0) {
            lock_ObtainMutex(&cp->mx);
            mxheld = 1;
	    cp->timeout = time(0) + 7200;
        }
        else {
            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(cp->name, NULL, &ttl, cm_AddCellProc, &rock);
                if (code == 0) {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    mxheld = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS);
                    _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID);
		    cp->timeout = time(0) + ttl;
#ifdef DEBUG
                    fprintf(stderr, "cell %s: ttl=%d\n", cp->name, ttl);
#endif
		} else {
                    /* if we fail to find it this time, we'll just do nothing and leave the
                     * current entry alone
		     */
                    lock_ObtainMutex(&cp->mx);
                    mxheld = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_VLSERVER_INVALID);
                }
	    }
	}
    }

    if (code == 0)
        cm_RandomizeServer(&cp->vlServersp);

    if (mxheld)
        lock_ReleaseMutex(&cp->mx);

    return code ? NULL : cp;
}
Exemple #17
0
long test_InterlockedAnd(long volatile *value, long mask) {
  return _InterlockedAnd(value, mask);
}