/* * _NSFC_IsTimeToReplace - indicate if a file cache entry should be replaced */ static PRBool _NSFC_IsTimeToReplace(NSFCCache cip) { /* replaceFiles = PR_FALSE means we never replace entries */ if (cip->cfg.replaceFiles != PR_TRUE) { return PR_FALSE; } /* Don't replace entries unless the cache is full */ if (cip->cacheFull != PR_TRUE && cip->curFiles < cip->cfg.maxFiles) { return PR_FALSE; } /* minReplace specifies the minimum time between file entry replacements */ if (cip->cfg.minReplace != 0) { /* Bail if not enough time has elapsed since the last replacement */ PRIntervalTime now = PR_IntervalNow(); PRIntervalTime lastReplaced = cip->lastReplaced; if ((PRIntervalTime)(now - lastReplaced) < cip->cfg.minReplace) { return PR_FALSE; } /* Enough time has elapsed; were we the first to notice? */ PRIntervalTime set = PR_AtomicSet((PRInt32 *)&cip->lastReplaced, now); if (set != lastReplaced) { return PR_FALSE; } cip->cacheFull = PR_FALSE; } return PR_TRUE; }
PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( PRCallOnceType *once, PRCallOnceWithArgFN func, void *arg) { if (!_pr_initialized) _PR_ImplicitInitialization(); if (!once->initialized) { if (PR_AtomicSet(&once->inProgress, 1) == 0) { once->status = (*func)(arg); PR_Lock(mod_init.ml); once->initialized = 1; PR_NotifyAllCondVar(mod_init.cv); PR_Unlock(mod_init.ml); } else { PR_Lock(mod_init.ml); while (!once->initialized) { PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock(mod_init.ml); } } else { if (PR_SUCCESS != once->status) { PR_SetError(PR_CALL_ONCE_ERROR, 0); } } return once->status; }
NS_IMETHODIMP sbDeviceProgressListener::OnJobProgress(sbIJobProgress* aJobProgress) { // Validate arguments. NS_ENSURE_ARG_POINTER(aJobProgress); // Function variables. nsresult rv; // Update the device status. if (mDeviceStatusHelper) { // Get the job progress. PRUint32 progress; PRUint32 total; rv = aJobProgress->GetProgress(&progress); NS_ENSURE_SUCCESS(rv, rv); rv = aJobProgress->GetTotal(&total); NS_ENSURE_SUCCESS(rv, rv); // Update the device status. if (total > 0) { mDeviceStatusHelper->ItemProgress(static_cast<double>(progress) / static_cast<double>(total)); } } // Get the job status. PRUint16 status; rv = aJobProgress->GetStatus(&status); NS_ENSURE_SUCCESS(rv, rv); // Check for job completion. if (status != sbIJobProgress::STATUS_RUNNING) { if (mCompleteNotifyMonitor) { nsAutoMonitor monitor(mCompleteNotifyMonitor); PR_AtomicSet(&mIsComplete, 1); monitor.Notify(); } else { PR_AtomicSet(&mIsComplete, 1); } } return NS_OK; }
void nsDOMWorkerTimeout::ReleaseSpinlock() { #ifdef DEBUG PRInt32 suspended = #endif PR_AtomicSet(&mSuspendSpinlock, 0); NS_ASSERTION(suspended == 1, "Huh?!"); }
NSFC_ReleaseEntryWriteLock(NSFCCache cip, NSFCEntryImpl *nep) { PRInt32 rv; PR_ASSERT(nep->refcnt >=1 && nep->fWriting); rv = PR_AtomicSet(&nep->fWriting, 0); PR_ASSERT(rv == 1); /* Cache contents have been modified */ cip->sig++; }
nsresult TimerThread::Init() { PR_LOG(gTimerLog, PR_LOG_DEBUG, ("TimerThread::Init [%d]\n", mInitialized)); if (mInitialized) { if (!mThread) return NS_ERROR_FAILURE; return NS_OK; } if (PR_AtomicSet(&mInitInProgress, 1) == 0) { // We hold on to mThread to keep the thread alive. nsresult rv = NS_NewThread(getter_AddRefs(mThread), this); if (NS_FAILED(rv)) { mThread = nsnull; } else { nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1"); // We must not use the observer service from a background thread! if (observerService && !NS_IsMainThread()) { nsCOMPtr<nsIObserverService> result = nsnull; NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIObserverService), observerService, NS_PROXY_ASYNC, getter_AddRefs(result)); observerService.swap(result); } // We'll be released at xpcom shutdown if (observerService) { observerService->AddObserver(this, "sleep_notification", PR_FALSE); observerService->AddObserver(this, "wake_notification", PR_FALSE); } } PR_Lock(mLock); mInitialized = PR_TRUE; PR_NotifyAllCondVar(mCondVar); PR_Unlock(mLock); } else { PR_Lock(mLock); while (!mInitialized) { PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock(mLock); } if (!mThread) return NS_ERROR_FAILURE; return NS_OK; }
// Called from any thread NS_IMETHODIMP nsBaseAppShell::OnDispatchedEvent(nsIThreadInternal *thr) { if (mBlockNativeEvent) return NS_OK; PRInt32 lastVal = PR_AtomicSet(&mNativeEventPending, 1); if (lastVal == 1) return NS_OK; ScheduleNativeEventCallback(); return NS_OK; }
PRIntn main(PRIntn argc, char **argv) { PRInt32 rv, test, result = 0; PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); test = -2; rv = PR_AtomicIncrement(&test); result = result | ((rv < 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicIncrement(%d) == %d: %s\n", test, rv, (rv < 0) ? "PASSED" : "FAILED"); rv = PR_AtomicIncrement(&test); result = result | ((rv == 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicIncrement(%d) == %d: %s\n", test, rv, (rv == 0) ? "PASSED" : "FAILED"); rv = PR_AtomicIncrement(&test); result = result | ((rv > 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicIncrement(%d) == %d: %s\n", test, rv, (rv > 0) ? "PASSED" : "FAILED"); test = 2; rv = PR_AtomicDecrement(&test); result = result | ((rv > 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicDecrement(%d) == %d: %s\n", test, rv, (rv > 0) ? "PASSED" : "FAILED"); rv = PR_AtomicDecrement(&test); result = result | ((rv == 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicDecrement(%d) == %d: %s\n", test, rv, (rv == 0) ? "PASSED" : "FAILED"); rv = PR_AtomicDecrement(&test); result = result | ((rv < 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicDecrement(%d) == %d: %s\n", test, rv, (rv < 0) ? "PASSED" : "FAILED"); test = -2; rv = PR_AtomicSet(&test, 2); result = result | (((rv == -2) && (test == 2)) ? 0 : 1); PR_fprintf( output, "PR_AtomicSet(%d) == %d: %s\n", test, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); PR_fprintf( output, "Atomic operations test %s\n", (result == 0) ? "PASSED" : "FAILED"); return result; } /* main */
NSFC_AcquireEntryWriteLock(NSFCCache cip, NSFCEntryImpl *nep) { PRInt32 rv; /* * XXX elving this is unsafe on platforms that don't guarantee total store * order */ rv = PR_AtomicSet(&nep->fWriting, 1); /* We got it if the prior value was zero */ return (rv) ? NSFC_BUSY : NSFC_OK; }
// Called by nsAppShell's native event callback void nsBaseAppShell::NativeEventCallback() { PRInt32 hasPending = PR_AtomicSet(&mNativeEventPending, 0); if (hasPending == 0) return; // If DoProcessNextNativeEvent is on the stack, then we assume that we can // just unwind and let nsThread::ProcessNextEvent process the next event. // However, if we are called from a nested native event loop (maybe via some // plug-in or library function), then go ahead and process Gecko events now. if (mEventloopNestingState == eEventloopXPCOM) { mEventloopNestingState = eEventloopOther; // XXX there is a tiny risk we will never get a new NativeEventCallback, // XXX see discussion in bug 389931. return; } // nsBaseAppShell::Run is not being used to pump events, so this may be // our only opportunity to process pending gecko events. nsIThread *thread = NS_GetCurrentThread(); PRBool prevBlockNativeEvent = mBlockNativeEvent; if (mEventloopNestingState == eEventloopOther) { if (!NS_HasPendingEvents(thread)) return; // We're in a nested native event loop and have some gecko events to // process. While doing that we block processing native events from the // appshell - instead, we want to get back to the nested native event // loop ASAP (bug 420148). mBlockNativeEvent = PR_TRUE; } ++mEventloopNestingLevel; EventloopNestingState prevVal = mEventloopNestingState; NS_ProcessPendingEvents(thread, THREAD_EVENT_STARVATION_LIMIT); mProcessedGeckoEvents = PR_TRUE; mEventloopNestingState = prevVal; mBlockNativeEvent = prevBlockNativeEvent; // Continue processing pending events later (we don't want to starve the // embedders event loop). if (NS_HasPendingEvents(thread)) DoProcessMoreGeckoEvents(); --mEventloopNestingLevel; }
void nsDOMWorkerTimeout::AcquireSpinlock() { PRUint32 loopCount = 0; while (PR_AtomicSet(&mSuspendSpinlock, 1) == 1) { if (++loopCount > SUSPEND_SPINLOCK_COUNT) { LOG(("AcquireSpinlock taking too long (looped %u times), yielding.", loopCount)); loopCount = 0; PR_Sleep(PR_INTERVAL_NO_WAIT); } } #ifdef PR_LOGGING if (loopCount) { LOG(("AcquireSpinlock needed %u loops", loopCount)); } #endif }
nsresult TimerThread::Init() { if (mInitialized) { if (!mThread) return NS_ERROR_FAILURE; return NS_OK; } if (PR_AtomicSet(&mInitInProgress, 1) == 0) { nsresult rv; mEventQueueService = do_GetService("@mozilla.org/event-queue-service;1", &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIObserverService> observerService (do_GetService("@mozilla.org/observer-service;1", &rv)); if (NS_SUCCEEDED(rv)) { // We hold on to mThread to keep the thread alive. rv = NS_NewThread(getter_AddRefs(mThread), NS_STATIC_CAST(nsIRunnable*, this), 0, PR_JOINABLE_THREAD, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD); if (NS_FAILED(rv)) { mThread = nsnull; } else { // We'll be released at xpcom shutdown observerService->AddObserver(this, "sleep_notification", PR_FALSE); observerService->AddObserver(this, "wake_notification", PR_FALSE); } } } PR_Lock(mLock); mInitialized = PR_TRUE; PR_NotifyAllCondVar(mCondVar); PR_Unlock(mLock); }
PR_IMPLEMENT(PRStatus) PR_CallOnce( PRCallOnceType *once, PRCallOnceFN func) { if (!_pr_initialized) _PR_ImplicitInitialization(); if (!once->initialized) { if (PR_AtomicSet(&once->inProgress, 1) == 0) { once->status = (*func)(); PR_Lock(mod_init.ml); once->initialized = 1; PR_NotifyAllCondVar(mod_init.cv); PR_Unlock(mod_init.ml); } else { PR_Lock(mod_init.ml); while (!once->initialized) { PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock(mod_init.ml); } } return once->status; }
nsresult nsMemoryImpl::FlushMemory(const PRUnichar* aReason, PRBool aImmediate) { nsresult rv = NS_OK; if (aImmediate) { // They've asked us to run the flusher *immediately*. We've // got to be on the UI main thread for us to be able to do // that...are we? if (!NS_IsMainThread()) { NS_ERROR("can't synchronously flush memory: not on UI thread"); return NS_ERROR_FAILURE; } } PRInt32 lastVal = PR_AtomicSet(&sIsFlushing, 1); if (lastVal) return NS_OK; PRIntervalTime now = PR_IntervalNow(); // Run the flushers immediately if we can; otherwise, proxy to the // UI thread an run 'em asynchronously. if (aImmediate) { rv = RunFlushers(aReason); } else { // Don't broadcast more than once every 1000ms to avoid being noisy if (PR_IntervalToMicroseconds(now - sLastFlushTime) > 1000) { sFlushEvent.mReason = aReason; rv = NS_DispatchToMainThread(&sFlushEvent, NS_DISPATCH_NORMAL); } } sLastFlushTime = now; return rv; }
long atomic_set(atomic_t *value, atomic_t newvalue) { return PR_AtomicSet((PRInt32*)value, (PRInt32)newvalue); }
static void fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced) { CERTCertTrust* trust = NULL; NSSTrust *nssTrust; NSSCryptoContext *context = c->object.cryptoContext; nssCryptokiInstance *instance; NSSUTF8 *stanNick = NULL; /* We are holding the base class object's lock on entry of this function * This lock protects writes to fields of the CERTCertificate . * It is also needed by some functions to compute values such as trust. */ instance = get_cert_instance(c); if (instance) { stanNick = instance->label; } else if (context) { stanNick = c->object.tempName; } /* fill other fields needed by NSS3 functions using CERTCertificate */ if ((!cc->nickname && stanNick) || forced) { PRStatus nssrv; int nicklen, tokenlen, len; NSSUTF8 *tokenName = NULL; char *nick; if (instance && (!PK11_IsInternal(instance->token->pk11slot) || (stanNick && PORT_Strchr(stanNick, ':') != NULL))) { tokenName = nssToken_GetName(instance->token); tokenlen = nssUTF8_Size(tokenName, &nssrv); } else { /* don't use token name for internal slot; 3.3 didn't */ tokenlen = 0; } if (stanNick) { nicklen = nssUTF8_Size(stanNick, &nssrv); len = tokenlen + nicklen; nick = PORT_ArenaAlloc(cc->arena, len); if (tokenName) { memcpy(nick, tokenName, tokenlen-1); nick[tokenlen-1] = ':'; memcpy(nick+tokenlen, stanNick, nicklen-1); } else { memcpy(nick, stanNick, nicklen-1); } nick[len-1] = '\0'; cc->nickname = nick; } else { cc->nickname = NULL; } } if (context) { /* trust */ nssTrust = nssCryptoContext_FindTrustForCertificate(context, c); if (nssTrust) { trust = cert_trust_from_stan_trust(nssTrust, cc->arena); if (trust) { /* we should destroy cc->trust before replacing it, but it's allocated in cc->arena, so memory growth will occur on each refresh */ cc->trust = trust; } nssTrust_Destroy(nssTrust); } } else if (instance) { /* slot */ if (cc->slot != instance->token->pk11slot) { if (cc->slot) { PK11_FreeSlot(cc->slot); } cc->slot = PK11_ReferenceSlot(instance->token->pk11slot); } cc->ownSlot = PR_TRUE; /* pkcs11ID */ cc->pkcs11ID = instance->handle; /* trust */ trust = nssTrust_GetCERTCertTrustForCert(c, cc); if (trust) { /* we should destroy cc->trust before replacing it, but it's allocated in cc->arena, so memory growth will occur on each refresh */ cc->trust = trust; } nssCryptokiObject_Destroy(instance); } /* database handle is now the trust domain */ cc->dbhandle = c->object.trustDomain; /* subjectList ? */ /* istemp and isperm are supported in NSS 3.4 */ cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */ cc->isperm = PR_TRUE; /* by default */ /* pointer back */ cc->nssCertificate = c; if (trust) { /* force the cert type to be recomputed to include trust info */ PRUint32 nsCertType = cert_ComputeCertType(cc); /* Assert that it is safe to cast &cc->nsCertType to "PRInt32 *" */ PORT_Assert(sizeof(cc->nsCertType) == sizeof(PRInt32)); PR_AtomicSet((PRInt32 *)&cc->nsCertType, nsCertType); } }
int main(int argc, char **argv) { PRInt32 rv, oldval, test, result = 0; PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput); /***********************/ /* Test the functions. */ /***********************/ oldval = test = -2; rv = PR_AtomicIncrement(&test); result = result | ((rv == -1) ? 0 : 1); PR_fprintf( output, "PR_AtomicIncrement(%d) == %d: %s\n", oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); oldval = test; rv = PR_AtomicIncrement(&test); result = result | ((rv == 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicIncrement(%d) == %d: %s\n", oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); oldval = test; rv = PR_AtomicIncrement(&test); result = result | ((rv == 1) ? 0 : 1); PR_fprintf( output, "PR_AtomicIncrement(%d) == %d: %s\n", oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); oldval = test = -2; rv = PR_AtomicAdd(&test,1); result = result | ((rv == -1) ? 0 : 1); PR_fprintf( output, "PR_AtomicAdd(%d,%d) == %d: %s\n", oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED"); oldval = test; rv = PR_AtomicAdd(&test, 4); result = result | ((rv == 3) ? 0 : 1); PR_fprintf( output, "PR_AtomicAdd(%d,%d) == %d: %s\n", oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED"); oldval = test; rv = PR_AtomicAdd(&test, -6); result = result | ((rv == -3) ? 0 : 1); PR_fprintf( output, "PR_AtomicAdd(%d,%d) == %d: %s\n", oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED"); oldval = test = 2; rv = PR_AtomicDecrement(&test); result = result | ((rv == 1) ? 0 : 1); PR_fprintf( output, "PR_AtomicDecrement(%d) == %d: %s\n", oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); oldval = test; rv = PR_AtomicDecrement(&test); result = result | ((rv == 0) ? 0 : 1); PR_fprintf( output, "PR_AtomicDecrement(%d) == %d: %s\n", oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); oldval = test; rv = PR_AtomicDecrement(&test); result = result | ((rv == -1) ? 0 : 1); PR_fprintf( output, "PR_AtomicDecrement(%d) == %d: %s\n", oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); /* set to a different value */ oldval = test = -2; rv = PR_AtomicSet(&test, 2); result = result | (((rv == -2) && (test == 2)) ? 0 : 1); PR_fprintf( output, "PR_AtomicSet(%d, %d) == %d: %s\n", oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); /* set to the same value */ oldval = test = -2; rv = PR_AtomicSet(&test, -2); result = result | (((rv == -2) && (test == -2)) ? 0 : 1); PR_fprintf( output, "PR_AtomicSet(%d, %d) == %d: %s\n", oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED"); /***********************/ /* Test the macros. */ /***********************/ oldval = test = -2; rv = PR_ATOMIC_INCREMENT(&test); result = result | ((rv == -1) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); oldval = test; rv = PR_ATOMIC_INCREMENT(&test); result = result | ((rv == 0) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); oldval = test; rv = PR_ATOMIC_INCREMENT(&test); result = result | ((rv == 1) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_INCREMENT(%d) == %d: %s\n", oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); oldval = test = -2; rv = PR_ATOMIC_ADD(&test,1); result = result | ((rv == -1) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED"); oldval = test; rv = PR_ATOMIC_ADD(&test, 4); result = result | ((rv == 3) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED"); oldval = test; rv = PR_ATOMIC_ADD(&test, -6); result = result | ((rv == -3) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_ADD(%d,%d) == %d: %s\n", oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED"); oldval = test = 2; rv = PR_ATOMIC_DECREMENT(&test); result = result | ((rv == 1) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", oldval, rv, (rv == 1) ? "PASSED" : "FAILED"); oldval = test; rv = PR_ATOMIC_DECREMENT(&test); result = result | ((rv == 0) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", oldval, rv, (rv == 0) ? "PASSED" : "FAILED"); oldval = test; rv = PR_ATOMIC_DECREMENT(&test); result = result | ((rv == -1) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_DECREMENT(%d) == %d: %s\n", oldval, rv, (rv == -1) ? "PASSED" : "FAILED"); /* set to a different value */ oldval = test = -2; rv = PR_ATOMIC_SET(&test, 2); result = result | (((rv == -2) && (test == 2)) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n", oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED"); /* set to the same value */ oldval = test = -2; rv = PR_ATOMIC_SET(&test, -2); result = result | (((rv == -2) && (test == -2)) ? 0 : 1); PR_fprintf( output, "PR_ATOMIC_SET(%d, %d) == %d: %s\n", oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED"); PR_fprintf( output, "Atomic operations test %s\n", (result == 0) ? "PASSED" : "FAILED"); return result; } /* main */