void terminateWorkerThreads(void) { int i; VLOG(("httpserv: server_thread: waiting on stopping")); PZ_Lock(qLock); PZ_NotifyAllCondVar(jobQNotEmptyCv); PZ_Unlock(qLock); /* Wait for worker threads to terminate. */ for (i = 0; i < maxThreads; ++i) { perThread *slot = threads + i; if (slot->prThread) { PR_JoinThread(slot->prThread); } } /* The worker threads empty the jobQ before they terminate. */ PZ_Lock(qLock); PORT_Assert(threadCount == 0); PORT_Assert(PR_CLIST_IS_EMPTY(&jobQ)); PZ_Unlock(qLock); DESTROY_CONDVAR(jobQNotEmptyCv); DESTROY_CONDVAR(freeListNotEmptyCv); DESTROY_CONDVAR(threadCountChangeCv); PR_DestroyLock(lastLoadedCrlLock); DESTROY_LOCK(qLock); PR_Free(jobTable); PR_Free(threads); }
static void port_ArenaRelease(PLArenaPool *arena, void *mark, PRBool zero) { PORTArenaPool *pool = (PORTArenaPool *)arena; if (ARENAPOOL_MAGIC == pool->magic ) { PZ_Lock(pool->lock); #ifdef THREADMARK { threadmark_mark **pw, *tm; if (PR_GetCurrentThread() != pool->marking_thread ) { PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_Assert(0); return /* no error indication available */ ; } pw = &pool->first_mark; while( *pw && (mark != (*pw)->mark) ) { pw = &(*pw)->next; } if (! *pw ) { /* bad mark */ PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_Assert(0); return /* no error indication available */ ; } tm = *pw; *pw = (threadmark_mark *)NULL; if (zero) { port_ArenaZeroAfterMark(arena, mark); } PL_ARENA_RELEASE(arena, mark); if (! pool->first_mark ) { pool->marking_thread = (PRThread *)NULL; } } #else /* THREADMARK */ if (zero) { port_ArenaZeroAfterMark(arena, mark); } PL_ARENA_RELEASE(arena, mark); #endif /* THREADMARK */ PZ_Unlock(pool->lock); } else { if (zero) { port_ArenaZeroAfterMark(arena, mark); } PL_ARENA_RELEASE(arena, mark); } }
void * PORT_ArenaMark(PLArenaPool *arena) { void * result; PORTArenaPool *pool = (PORTArenaPool *)arena; if (ARENAPOOL_MAGIC == pool->magic ) { PZ_Lock(pool->lock); #ifdef THREADMARK { threadmark_mark *tm, **pw; PRThread * currentThread = PR_GetCurrentThread(); if (! pool->marking_thread ) { /* First mark */ pool->marking_thread = currentThread; } else if (currentThread != pool->marking_thread ) { PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_Assert(0); return NULL; } result = PL_ARENA_MARK(arena); PL_ARENA_ALLOCATE(tm, arena, sizeof(threadmark_mark)); if (!tm) { PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); return NULL; } tm->mark = result; tm->next = (threadmark_mark *)NULL; pw = &pool->first_mark; while( *pw ) { pw = &(*pw)->next; } *pw = tm; } #else /* THREADMARK */ result = PL_ARENA_MARK(arena); #endif /* THREADMARK */ PZ_Unlock(pool->lock); } else { /* a "pure" NSPR arena */ result = PL_ARENA_MARK(arena); } return result; }
NSS_IMPLEMENT void nssTrustDomain_UnlockCertCache ( NSSTrustDomain *td ) { PZ_Unlock(td->cache->lock); }
SECStatus launch_threads( startFn *startFunc, PRFileDesc *a, PRFileDesc *b, int c, PRBool local) { int i; SECStatus rv = SECSuccess; /* create the thread management serialization structs */ qLock = PZ_NewLock(nssILockSelfServ); jobQNotEmptyCv = PZ_NewCondVar(qLock); freeListNotEmptyCv = PZ_NewCondVar(qLock); threadCountChangeCv = PZ_NewCondVar(qLock); /* create monitor for crl reload procedure */ lastLoadedCrlLock = PR_NewLock(); /* allocate the array of thread slots */ threads = PR_Calloc(maxThreads, sizeof(perThread)); if ( NULL == threads ) { fprintf(stderr, "Oh Drat! Can't allocate the perThread array\n"); return SECFailure; } /* 5 is a little extra, intended to keep the jobQ from underflowing. ** That is, from going empty while not stopping and clients are still ** trying to contact us. */ rv = setupJobs(maxThreads + 5); if (rv != SECSuccess) return rv; PZ_Lock(qLock); for (i = 0; i < maxThreads; ++i) { perThread * slot = threads + i; slot->state = rs_running; slot->a = a; slot->b = b; slot->c = c; slot->startFunc = startFunc; slot->prThread = PR_CreateThread(PR_USER_THREAD, thread_wrapper, slot, PR_PRIORITY_NORMAL, (PR_TRUE==local)?PR_LOCAL_THREAD:PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (slot->prThread == NULL) { printf("selfserv: Failed to launch thread!\n"); slot->state = rs_idle; rv = SECFailure; break; } ++threadCount; } PZ_Unlock(qLock); return rv; }
void nssSlot_ExitMonitor(NSSSlot *slot) { if (slot->lock) { PZ_Unlock(slot->lock); } }
NSS_IMPLEMENT PRStatus nssSession_ExitMonitor ( nssSession *s ) { return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS; }
/* * If zero is true, zeroize the arena memory before freeing it. */ void PORT_FreeArena(PLArenaPool *arena, PRBool zero) { PORTArenaPool *pool = (PORTArenaPool *)arena; PRLock *lock = (PRLock *)0; size_t len = sizeof *arena; if (!pool) return; if (ARENAPOOL_MAGIC == pool->magic) { len = sizeof *pool; lock = pool->lock; PZ_Lock(lock); } if (zero) { PL_ClearArenaPool(arena, 0); } (void)PR_CallOnce(&setupUseFreeListOnce, &SetupUseFreeList); if (useFreeList) { PL_FreeArenaPool(arena); } else { PL_FinishArenaPool(arena); } PORT_ZFree(arena, len); if (lock) { PZ_Unlock(lock); PZ_DestroyLock(lock); } }
/* * nssHash_Add * */ NSS_IMPLEMENT PRStatus nssHash_Add ( nssHash *hash, const void *key, const void *value ) { PRStatus error = PR_FAILURE; PLHashEntry *he; PZ_Lock(hash->mutex); he = PL_HashTableAdd(hash->plHashTable, key, (void *)value); if( (PLHashEntry *)NULL == he ) { nss_SetError(NSS_ERROR_NO_MEMORY); } else if (he->value != value) { nss_SetError(NSS_ERROR_HASH_COLLISION); } else { hash->count++; error = PR_SUCCESS; } (void)PZ_Unlock(hash->mutex); return error; }
int jobLoop(PRFileDesc *a, PRFileDesc *b, int c) { PRCList *myLink = 0; JOB *myJob; PZ_Lock(qLock); do { myLink = 0; while (PR_CLIST_IS_EMPTY(&jobQ) && !stopping) { PZ_WaitCondVar(jobQNotEmptyCv, PR_INTERVAL_NO_TIMEOUT); } if (!PR_CLIST_IS_EMPTY(&jobQ)) { myLink = PR_LIST_HEAD(&jobQ); PR_REMOVE_AND_INIT_LINK(myLink); } PZ_Unlock(qLock); myJob = (JOB *)myLink; /* myJob will be null when stopping is true and jobQ is empty */ if (!myJob) break; handle_connection(myJob->tcp_sock, myJob->model_sock, myJob->requestCert); PZ_Lock(qLock); PR_APPEND_LINK(myLink, &freeJobs); PZ_NotifyCondVar(freeListNotEmptyCv); } while (PR_TRUE); return 0; }
/* * If zero is true, zeroize the arena memory before freeing it. */ void PORT_FreeArena(PLArenaPool *arena, PRBool zero) { PORTArenaPool *pool = (PORTArenaPool *)arena; PRLock * lock = (PRLock *)0; size_t len = sizeof *arena; static PRBool checkedEnv = PR_FALSE; static PRBool doFreeArenaPool = PR_FALSE; if (!pool) return; if (ARENAPOOL_MAGIC == pool->magic ) { len = sizeof *pool; lock = pool->lock; PZ_Lock(lock); } if (!checkedEnv) { /* no need for thread protection here */ doFreeArenaPool = (PR_GetEnv("NSS_DISABLE_ARENA_FREE_LIST") == NULL); checkedEnv = PR_TRUE; } if (zero) { PL_ClearArenaPool(arena, 0); } if (doFreeArenaPool) { PL_FreeArenaPool(arena); } else { PL_FinishArenaPool(arena); } PORT_ZFree(arena, len); if (lock) { PZ_Unlock(lock); PZ_DestroyLock(lock); } }
/* we can only get here if we've destroyed the module, or some one has * erroneously freed a slot that wasn't referenced. */ void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot) { PRBool willfree = PR_FALSE; if (fromSlot) { PORT_Assert(module->refCount == 0); PZ_Lock(module->refLock); if (module->slotCount-- == 1) { willfree = PR_TRUE; } PORT_Assert(willfree || (module->slotCount > 0)); PZ_Unlock(module->refLock); if (!willfree) return; } if (module == pendingModule) { pendingModule = NULL; } if (module->loaded) { SECMOD_UnloadModule(module); } PZ_DestroyLock(module->refLock); PORT_FreeArena(module->arena,PR_FALSE); secmod_PrivateModuleCount--; }
/* * make a new reference to a module so It doesn't go away on us */ SECMODModule * SECMOD_ReferenceModule(SECMODModule *module) { PZ_Lock(module->refLock); PORT_Assert(module->refCount > 0); module->refCount++; PZ_Unlock(module->refLock); return module; }
void PK11_ExitContextMonitor(PK11Context *cx) { /* if we own the session and our slot is ThreadSafe, only monitor * the Context */ if ((cx->ownSession) && (cx->slot->isThreadSafe)) { /* Should this use monitors instead? */ PZ_Unlock(cx->sessionLock); } else { PK11_ExitSlotMonitor(cx->slot); } }
NSS_IMPLEMENT void nssCertificateStore_DumpStoreInfo ( nssCertificateStore *store, void (* cert_dump_iter)(const void *, void *, void *), void *arg ) { PZ_Lock(store->lock); nssHash_Iterate(store->issuer_and_serial, cert_dump_iter, arg); PZ_Unlock(store->lock); }
void PORT_ArenaUnmark(PLArenaPool *arena, void *mark) { #ifdef THREADMARK PORTArenaPool *pool = (PORTArenaPool *)arena; if (ARENAPOOL_MAGIC == pool->magic ) { threadmark_mark **pw, *tm; PZ_Lock(pool->lock); if (PR_GetCurrentThread() != pool->marking_thread ) { PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_Assert(0); return /* no error indication available */ ; } pw = &pool->first_mark; while( ((threadmark_mark *)NULL != *pw) && (mark != (*pw)->mark) ) { pw = &(*pw)->next; } if ((threadmark_mark *)NULL == *pw ) { /* bad mark */ PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_Assert(0); return /* no error indication available */ ; } tm = *pw; *pw = (threadmark_mark *)NULL; if (! pool->first_mark ) { pool->marking_thread = (PRThread *)NULL; } PZ_Unlock(pool->lock); } #endif /* THREADMARK */ }
void * PORT_ArenaAlloc(PLArenaPool *arena, size_t size) { void *p = NULL; PORTArenaPool *pool = (PORTArenaPool *)arena; if (size <= 0) { size = 1; } if (size > MAX_SIZE) { /* you lose. */ } else /* Is it one of ours? Assume so and check the magic */ if (ARENAPOOL_MAGIC == pool->magic ) { PZ_Lock(pool->lock); #ifdef THREADMARK /* Most likely one of ours. Is there a thread id? */ if (pool->marking_thread && pool->marking_thread != PR_GetCurrentThread() ) { /* Another thread holds a mark in this arena */ PZ_Unlock(pool->lock); PORT_SetError(SEC_ERROR_NO_MEMORY); PORT_Assert(0); return NULL; } /* tid != null */ #endif /* THREADMARK */ PL_ARENA_ALLOCATE(p, arena, size); PZ_Unlock(pool->lock); } else { PL_ARENA_ALLOCATE(p, arena, size); } if (!p) { ++port_allocFailures; PORT_SetError(SEC_ERROR_NO_MEMORY); } return(p); }
/* * stub files for legacy db's to be able to encrypt and decrypt * various keys and attributes. */ static SECStatus sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText) { SFTKDBHandle *handle = sdb->app_private; SECStatus rv; SECItem *oldKey = NULL; if (handle == NULL) { return SECFailure; } /* if we aren't th handle, try the other handle */ oldKey = handle->oldKey; if (handle->type != SFTK_KEYDB_TYPE) { handle = handle->peerDB; } /* not a key handle */ if (handle == NULL || handle->passwordLock == NULL) { return SECFailure; } PZ_Lock(handle->passwordLock); if (handle->passwordKey.data == NULL) { PZ_Unlock(handle->passwordLock); /* PORT_SetError */ return SECFailure; } #if defined(PKCS11_DB_DATA_KEY_USE_KEYSTORE) || defined(PKCS11_DB_DATA_KEY_USE_KEYCHAIN) rv = sftkdb_DecryptAttributeByDbDataKey( cipherText, plainText); #else rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey, cipherText, plainText); #endif PZ_Unlock(handle->passwordLock); return rv; }
NSS_IMPLEMENT void nssCertificateStore_Unlock ( nssCertificateStore *store, nssCertificateStoreTrace* in, nssCertificateStoreTrace* out ) { #ifdef DEBUG PORT_Assert(in); PORT_Assert(out); out->store = store; out->lock = store->lock; out->unlocked = PR_TRUE; PORT_Assert(in->store == out->store); PORT_Assert(in->lock == out->lock); PORT_Assert(in->locked); PZ_Unlock(out->lock); #else PZ_Unlock(store->lock); #endif }
void thread_wrapper(void *arg) { perThread *slot = (perThread *)arg; slot->rv = (*slot->startFunc)(slot->a, slot->b, slot->c); /* notify the thread exit handler. */ PZ_Lock(qLock); slot->state = rs_zombie; --threadCount; PZ_NotifyAllCondVar(threadCountChangeCv); PZ_Unlock(qLock); }
/* * If zero is true, zeroize the arena memory before freeing it. */ void PORT_FreeArena(PLArenaPool *arena, PRBool zero) { PORTArenaPool *pool = (PORTArenaPool *)arena; PRLock * lock = (PRLock *)0; size_t len = sizeof *arena; extern const PRVersionDescription * libVersionPoint(void); static const PRVersionDescription * pvd; static PRBool doFreeArenaPool = PR_FALSE; if (ARENAPOOL_MAGIC == pool->magic ) { len = sizeof *pool; lock = pool->lock; PZ_Lock(lock); } if (!pvd) { /* Each of NSPR's DLLs has a function libVersionPoint(). ** We could do a lot of extra work to be sure we're calling the ** one in the DLL that holds PR_FreeArenaPool, but instead we ** rely on the fact that ALL NSPR DLLs in the same directory ** must be from the same release, and we call which ever one we get. */ /* no need for thread protection here */ pvd = libVersionPoint(); if ((pvd->vMajor > 4) || (pvd->vMajor == 4 && pvd->vMinor > 1) || (pvd->vMajor == 4 && pvd->vMinor == 1 && pvd->vPatch >= 1)) { const char *ev = PR_GetEnv("NSS_DISABLE_ARENA_FREE_LIST"); if (!ev) doFreeArenaPool = PR_TRUE; } } if (zero) { PLArena *a; for (a = arena->first.next; a; a = a->next) { PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); memset((void *)a->base, 0, a->avail - a->base); } } if (doFreeArenaPool) { PL_FreeArenaPool(arena); } else { PL_FinishArenaPool(arena); } PORT_ZFree(arena, len); if (lock) { PZ_Unlock(lock); PZ_DestroyLock(lock); } }
NSS_IMPLEMENT NSSCertificate * nssCertificateStore_FindCertificateByIssuerAndSerialNumber ( nssCertificateStore *store, NSSDER *issuer, NSSDER *serial ) { NSSCertificate *rvCert = NULL; PZ_Lock(store->lock); rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked ( store, issuer, serial); PZ_Unlock(store->lock); return rvCert; }
/* * nssHash_Count * */ NSS_IMPLEMENT PRUint32 nssHash_Count ( nssHash *hash ) { PRUint32 count; PZ_Lock(hash->mutex); count = hash->count; (void)PZ_Unlock(hash->mutex); return count; }
/* * nssHash_Lookup * */ NSS_IMPLEMENT void * nssHash_Lookup ( nssHash *hash, const void *it ) { void *rv; PZ_Lock(hash->mutex); rv = PL_HashTableLookup(hash->plHashTable, it); (void)PZ_Unlock(hash->mutex); return rv; }
void * PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize) { PORTArenaPool *pool = (PORTArenaPool *)arena; PORT_Assert(newsize >= oldsize); if (ARENAPOOL_MAGIC == pool->magic ) { PZ_Lock(pool->lock); /* Do we do a THREADMARK check here? */ PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) ); PZ_Unlock(pool->lock); } else { PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) ); } return(ptr); }
NSS_IMPLEMENT nssSMIMEProfile * nssCertificateStore_FindSMIMEProfileForCertificate ( nssCertificateStore *store, NSSCertificate *cert ) { certificate_hash_entry *entry; nssSMIMEProfile *rvProfile = NULL; PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); if (entry && entry->profile) { rvProfile = nssSMIMEProfile_AddRef(entry->profile); } PZ_Unlock(store->lock); return rvProfile; }
NSS_IMPLEMENT NSSTrust * nssCertificateStore_FindTrustForCertificate ( nssCertificateStore *store, NSSCertificate *cert ) { certificate_hash_entry *entry; NSSTrust *rvTrust = NULL; PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); if (entry && entry->trust) { rvTrust = nssTrust_AddRef(entry->trust); } PZ_Unlock(store->lock); return rvTrust; }
NSS_EXTERN PRStatus nssCertificateStore_AddSMIMEProfile ( nssCertificateStore *store, nssSMIMEProfile *profile ) { NSSCertificate *cert; certificate_hash_entry *entry; cert = profile->certificate; PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); if (entry) { entry->profile = nssSMIMEProfile_AddRef(profile); } PZ_Unlock(store->lock); return (entry) ? PR_SUCCESS : PR_FAILURE; }
NSS_EXTERN PRStatus nssCertificateStore_AddTrust ( nssCertificateStore *store, NSSTrust *trust ) { NSSCertificate *cert; certificate_hash_entry *entry; cert = trust->certificate; PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); if (entry) { entry->trust = nssTrust_AddRef(trust); } PZ_Unlock(store->lock); return (entry) ? PR_SUCCESS : PR_FAILURE; }
/* destroy an existing module */ void SECMOD_DestroyModule(SECMODModule *module) { PRBool willfree = PR_FALSE; int slotCount; int i; PZ_Lock(module->refLock); if (module->refCount-- == 1) { willfree = PR_TRUE; } PORT_Assert(willfree || (module->refCount > 0)); PZ_Unlock(module->refLock); if (!willfree) { return; } if (module->parent != NULL) { SECMODModule *parent = module->parent; /* paranoia, don't loop forever if the modules are looped */ module->parent = NULL; SECMOD_DestroyModule(parent); } /* slots can't really disappear until our module starts freeing them, * so this check is safe */ slotCount = module->slotCount; if (slotCount == 0) { SECMOD_SlotDestroyModule(module,PR_FALSE); return; } /* now free all out slots, when they are done, they will cause the * module to disappear altogether */ for (i=0 ; i < slotCount; i++) { if (!module->slots[i]->disabled) { PK11_ClearSlotList(module->slots[i]); } PK11_FreeSlot(module->slots[i]); } /* WARNING: once the last slot has been freed is it possible (even likely) * that module is no more... touching it now is a good way to go south */ }