/* Try to attain a lock. Do not block! Returns true if the lock was attained. */ PUBLIC bool mprTrySpinLock(MprSpin *lock) { int rc; if (lock == 0) return 0; #if USE_MPR_LOCK mprTryLock(&lock->cs); #elif MACOSX rc = !OSSpinLockTry(&lock->cs); #elif ME_UNIX_LIKE && ME_COMPILER_HAS_SPINLOCK rc = pthread_spin_trylock(&lock->cs) != 0; #elif ME_UNIX_LIKE rc = pthread_mutex_trylock(&lock->cs) != 0; #elif ME_WIN_LIKE rc = (lock->freed) ? 0 : (TryEnterCriticalSection(&lock->cs) == 0); #elif VXWORKS rc = semTake(lock->cs, NO_WAIT) != OK; #endif #if ME_DEBUG && COSTLY if (rc == 0) { assert(lock->owner != mprGetCurrentOsThread()); lock->owner = mprGetCurrentOsThread(); } #endif return (rc) ? 0 : 1; }
/* Lock a mutex */ PUBLIC void mprSpinLock(MprSpin *lock) { if (lock == 0) return; #if ME_DEBUG /* Spin locks don't support recursive locking on all operating systems. */ assert(lock->owner != mprGetCurrentOsThread()); #endif #if USE_MPR_LOCK mprTryLock(&lock->cs); #elif MACOSX OSSpinLockLock(&lock->cs); #elif ME_UNIX_LIKE && ME_COMPILER_HAS_SPINLOCK pthread_spin_lock(&lock->cs); #elif ME_UNIX_LIKE pthread_mutex_lock(&lock->cs); #elif ME_WIN_LIKE if (!lock->freed) { EnterCriticalSection(&lock->cs); } #elif VXWORKS semTake(lock->cs, WAIT_FOREVER); #endif #if ME_DEBUG assert(lock->owner != mprGetCurrentOsThread()); lock->owner = mprGetCurrentOsThread(); #endif }
static void pruneCache(MprCache *cache, MprEvent *event) { MprTime when, factor; MprKey *kp; CacheItem *item; ssize excessKeys; if (!cache) { cache = shared; if (!cache) { return; } } if (event) { when = mprGetTime(); } else { /* Expire all items by setting event to NULL */ when = MAXINT64; } if (mprTryLock(cache->mutex)) { /* Check for expired items */ for (kp = 0; (kp = mprGetNextKey(cache->store, kp)) != 0; ) { item = (CacheItem*) kp->data; mprLog(6, "Cache: \"%s\" lifespan %d, expires in %d secs", item->key, item->lifespan / 1000, (item->expires - when) / 1000); if (item->expires && item->expires <= when) { mprLog(5, "Cache prune expired key %s", kp->key); removeItem(cache, item); } } mprAssert(cache->usedMem >= 0); /* If too many keys or too much memory used, prune keys that expire soonest. */ if (cache->maxKeys < MAXSSIZE || cache->maxMem < MAXSSIZE) { /* Look for those expiring in the next 5 minutes, then 20 mins, then 80 ... */ excessKeys = mprGetHashLength(cache->store) - cache->maxKeys; factor = 5 * 60 * MPR_TICKS_PER_SEC; when += factor; while (excessKeys > 0 || cache->usedMem > cache->maxMem) { for (kp = 0; (kp = mprGetNextKey(cache->store, kp)) != 0; ) { item = (CacheItem*) kp->data; if (item->expires && item->expires <= when) { mprLog(5, "Cache too big execess keys %Ld, mem %Ld, prune key %s", excessKeys, (cache->maxMem - cache->usedMem), kp->key); removeItem(cache, item); } } factor *= 4; when += factor; } } mprAssert(cache->usedMem >= 0); if (mprGetHashLength(cache->store) == 0) { if (event) { mprRemoveEvent(event); cache->timer = 0; } } unlock(cache); } }