PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads, PRUint32 stacksize) { PRThreadPool *tp; PRThread *thr; int i; wthread *wthrp; tp = alloc_threadpool(); if (NULL == tp) return NULL; tp->init_threads = initial_threads; tp->max_threads = max_threads; tp->stacksize = stacksize; PR_INIT_CLIST(&tp->jobq.list); PR_INIT_CLIST(&tp->ioq.list); PR_INIT_CLIST(&tp->timerq.list); PR_INIT_CLIST(&tp->jobq.wthreads); PR_INIT_CLIST(&tp->ioq.wthreads); PR_INIT_CLIST(&tp->timerq.wthreads); tp->shutdown = PR_FALSE; PR_Lock(tp->jobq.lock); for(i=0; i < initial_threads; ++i) { thr = PR_CreateThread(PR_USER_THREAD, wstart, tp, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize); PR_ASSERT(thr); wthrp = PR_NEWZAP(wthread); PR_ASSERT(wthrp); wthrp->thread = thr; PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); } tp->current_threads = initial_threads; thr = PR_CreateThread(PR_USER_THREAD, io_wstart, tp, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); PR_ASSERT(thr); wthrp = PR_NEWZAP(wthread); PR_ASSERT(wthrp); wthrp->thread = thr; PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads); thr = PR_CreateThread(PR_USER_THREAD, timer_wstart, tp, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); PR_ASSERT(thr); wthrp = PR_NEWZAP(wthread); PR_ASSERT(wthrp); wthrp->thread = thr; PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads); PR_Unlock(tp->jobq.lock); return tp; }
/* ** Create a new condition variable. ** "lock" is the lock to use with the condition variable. ** ** Condition variables are synchronization objects that threads can use ** to wait for some condition to occur. ** ** This may fail if memory is tight or if some operating system resource ** is low. */ PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) { PRCondVar *cvar; PR_ASSERT(lock != NULL); cvar = PR_NEWZAP(PRCondVar); if (cvar) { #ifdef _PR_GLOBAL_THREADS_ONLY if(_PR_MD_NEW_CV(&cvar->md)) { PR_DELETE(cvar); PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); return NULL; } #endif if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) { PR_DELETE(cvar); PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); return NULL; } cvar->lock = lock; PR_INIT_CLIST(&cvar->condQ); } else { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); } return cvar; }
/* * Notifies just get posted to the protecting mutex. The * actual notification is done when the lock is released so that * MP systems don't contend for a lock that they can't have. */ static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock, PRBool broadcast) { PRIntn index = 0; _MDNotified *notified = &lock->notified; while (1) { for (index = 0; index < notified->length; ++index) { if (notified->cv[index].cv == cvar) { if (broadcast) { notified->cv[index].times = -1; } else if (-1 != notified->cv[index].times) { notified->cv[index].times += 1; } return; } } /* if not full, enter new CV in this array */ if (notified->length < _MD_CV_NOTIFIED_LENGTH) break; /* if there's no link, create an empty array and link it */ if (NULL == notified->link) { notified->link = PR_NEWZAP(_MDNotified); } notified = notified->link; } /* A brand new entry in the array */ notified->cv[index].times = (broadcast) ? -1 : 1; notified->cv[index].cv = cvar; notified->length += 1; }
PR_IMPLEMENT(PRAlarmID*) PR_SetAlarm( PRAlarm *alarm, PRIntervalTime period, PRUint32 rate, PRPeriodicAlarmFn function, void *clientData) { /* * Create a new periodic alarm an existing current structure. * Set up the context and compute the first notify time (immediate). * Link the new ID into the head of the list (since it's notifying * immediately). */ PRAlarmID *id = PR_NEWZAP(PRAlarmID); if (!id) return NULL; id->alarm = alarm; PR_INIT_CLIST(&id->list); id->function = function; id->clientData = clientData; id->period = period; id->rate = rate; id->epoch = id->nextNotify = PR_IntervalNow(); (void)pr_PredictNextNotifyTime(id); PR_Lock(alarm->lock); PR_INSERT_BEFORE(&id->list, &alarm->timers); PR_NotifyCondVar(alarm->cond); PR_Unlock(alarm->lock); return id; } /* PR_SetAlarm */
static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp) { PRJob *jobp; jobp = PR_NEWZAP(PRJob); if (NULL == jobp) goto failed; if (joinable) { jobp->join_cv = PR_NewCondVar(tp->join_lock); jobp->join_wait = PR_TRUE; if (NULL == jobp->join_cv) goto failed; } else { jobp->join_cv = NULL; } #ifdef OPT_WINNT jobp->nt_notifier.jobp = jobp; #endif return jobp; failed: delete_job(jobp); PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return NULL; }
PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) { PRSemaphore *semaphore; static PRBool unwarned = PR_TRUE; if (!_pr_initialized) _PR_ImplicitInitialization(); if (unwarned) unwarned = _PR_Obsolete( "PR_NewSem", "locks & condition variables"); semaphore = PR_NEWZAP(PRSemaphore); if (NULL != semaphore) { PRLock *lock = PR_NewLock(); if (NULL != lock) { semaphore->cvar = PR_NewCondVar(lock); if (NULL != semaphore->cvar) { semaphore->count = value; return semaphore; } PR_DestroyLock(lock); } PR_Free(semaphore); } return NULL; }
/* ** Create a new monitor. */ PR_IMPLEMENT(PRMonitor*) PR_NewMonitor() { PRMonitor *mon; PRCondVar *cvar; PRLock *lock; mon = PR_NEWZAP(PRMonitor); if (mon) { lock = PR_NewLock(); if (!lock) { PR_DELETE(mon); return 0; } cvar = PR_NewCondVar(lock); if (!cvar) { PR_DestroyLock(lock); PR_DELETE(mon); return 0; } mon->cvar = cvar; mon->name = NULL; } return mon; }
static PRStatus MW_Init(void) { if (NULL != mw_lock) return PR_SUCCESS; if (NULL != (mw_lock = PR_NewLock())) { _PRGlobalState *state = PR_NEWZAP(_PRGlobalState); if (state == NULL) goto failed; PR_INIT_CLIST(&state->group_list); PR_Lock(mw_lock); if (NULL == mw_state) /* is it still NULL? */ { mw_state = state; /* if yes, set our value */ state = NULL; /* and indicate we've done the job */ max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL); } PR_Unlock(mw_lock); if (NULL != state) PR_DELETE(state); return PR_SUCCESS; } failed: return PR_FAILURE; } /* MW_Init */
/* ** Create a new semaphore. */ PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) { PRSemaphore *sem; PRCondVar *cvar; PRLock *lock; sem = PR_NEWZAP(PRSemaphore); if (sem) { #ifdef HAVE_CVAR_BUILT_ON_SEM _PR_MD_NEW_SEM(&sem->md, value); #else lock = PR_NewLock(); if (!lock) { PR_DELETE(sem); return NULL; } cvar = PR_NewCondVar(lock); if (!cvar) { PR_DestroyLock(lock); PR_DELETE(sem); return NULL; } sem->cvar = cvar; sem->count = value; #endif } return sem; }
PR_NewProcessAttr(void) { PRProcessAttr *attr; attr = PR_NEWZAP(PRProcessAttr); if (!attr) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); } return attr; }
static PRFileDesc *PushLayer(PRFileDesc *stack) { PRStatus rv; PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); layer->secret = PR_NEWZAP(PRFilePrivate); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); PR_ASSERT(PR_SUCCESS == rv); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); return stack; } /* PushLayer */
PR_IMPLEMENT(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group) { PRMWaitEnumerator *enumerator = PR_NEWZAP(PRMWaitEnumerator); if (NULL == enumerator) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); else { enumerator->group = group; enumerator->seal = _PR_ENUM_SEALED; } return enumerator; } /* PR_CreateMWaitEnumerator */
/* * add a job to the work queue */ static void add_to_jobq(PRThreadPool *tp, PRJob *jobp) { /* * add to jobq */ #ifdef OPT_WINNT PR_Lock(tp->jobq.lock); tp->jobq.cnt++; PR_Unlock(tp->jobq.lock); /* * notify worker thread(s) */ PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0, FALSE, &jobp->nt_notifier.overlapped); #else PR_Lock(tp->jobq.lock); PR_APPEND_LINK(&jobp->links,&tp->jobq.list); tp->jobq.cnt++; if ((tp->idle_threads < tp->jobq.cnt) && (tp->current_threads < tp->max_threads)) { wthread *wthrp; /* * increment thread count and unlock the jobq lock */ tp->current_threads++; PR_Unlock(tp->jobq.lock); /* create new worker thread */ wthrp = PR_NEWZAP(wthread); if (wthrp) { wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart, tp, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize); if (NULL == wthrp->thread) { PR_DELETE(wthrp); /* this sets wthrp to NULL */ } } PR_Lock(tp->jobq.lock); if (NULL == wthrp) { tp->current_threads--; } else { PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); } } /* * wakeup a worker thread */ PR_NotifyCondVar(tp->jobq.cv); PR_Unlock(tp->jobq.lock); #endif }
SECCipherFind *sec_CipherFindInit(PRBool onlyAllowed, secCPStruct *policy, long *ciphers) { SECCipherFind *find = PR_NEWZAP(SECCipherFind); if (find) { find->policy = policy; find->ciphers = ciphers; find->onlyAllowed = onlyAllowed; find->index = -1; } return find; }
static JSDSourceText* NewSource( JSDContext* jsdc, const char* url ) { JSDSourceText* jsdsrc = PR_NEWZAP(JSDSourceText); if( ! jsdsrc ) return NULL; jsdsrc->url = (char*) url; /* already a copy */ jsdsrc->status = JSD_SOURCE_INITED; jsdsrc->dirty = JS_TRUE; jsdsrc->alterCount = g_alterCount++ ; return jsdsrc; }
PR_IMPLEMENT(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size /* ignored */) { PRWaitGroup *wg = NULL; if (PR_FAILURE == MW_Init()) goto failed; if (NULL == (wg = PR_NEWZAP(PRWaitGroup))) goto failed; /* the wait group itself */ wg->ml = PR_NewLock(); if (NULL == wg->ml) goto failed_lock; wg->io_taken = PR_NewCondVar(wg->ml); if (NULL == wg->io_taken) goto failed_cvar0; wg->io_complete = PR_NewCondVar(wg->ml); if (NULL == wg->io_complete) goto failed_cvar1; wg->new_business = PR_NewCondVar(wg->ml); if (NULL == wg->new_business) goto failed_cvar2; wg->mw_manage = PR_NewCondVar(wg->ml); if (NULL == wg->mw_manage) goto failed_cvar3; PR_INIT_CLIST(&wg->group_link); PR_INIT_CLIST(&wg->io_ready); /* the waiters sequence */ wg->waiter = (_PRWaiterHash*)PR_CALLOC( sizeof(_PRWaiterHash) + (_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*))); if (NULL == wg->waiter) goto failed_waiter; wg->waiter->count = 0; wg->waiter->length = _PR_DEFAULT_HASH_LENGTH; PR_Lock(mw_lock); PR_APPEND_LINK(&wg->group_link, &mw_state->group_list); PR_Unlock(mw_lock); return wg; failed_waiter: PR_DestroyCondVar(wg->mw_manage); failed_cvar3: PR_DestroyCondVar(wg->new_business); failed_cvar2: PR_DestroyCondVar(wg->io_taken); failed_cvar1: PR_DestroyCondVar(wg->io_complete); failed_cvar0: PR_DestroyLock(wg->ml); failed_lock: PR_DELETE(wg); failed: return wg; } /* MW_CreateWaitGroup */
PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void) { PRMonitor *mon; PRCondVar *cvar; if (!_pr_initialized) _PR_ImplicitInitialization(); cvar = PR_NEWZAP(PRCondVar); if (NULL == cvar) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return NULL; } mon = PR_NEWZAP(PRMonitor); if (mon != NULL) { int rv; rv = _PT_PTHREAD_MUTEX_INIT(mon->lock.mutex, _pt_mattr); PR_ASSERT(0 == rv); _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); mon->cvar = cvar; rv = _PT_PTHREAD_COND_INIT(mon->cvar->cv, _pt_cvar_attr); PR_ASSERT(0 == rv); mon->entryCount = 0; mon->cvar->lock = &mon->lock; if (0 != rv) { PR_DELETE(mon); PR_DELETE(cvar); mon = NULL; } } return mon; } /* PR_NewMonitor */
PR_IMPLEMENT(PRLock*) PR_NewLock(void) { PRLock *lock; if (!_pr_initialized) _PR_ImplicitInitialization(); lock = PR_NEWZAP(PRLock); if (lock) { if (_PR_InitLock(lock) != PR_SUCCESS) { PR_DELETE(lock); return NULL; } } return lock; }
PR_NewSem (PRUintn value) { PRSemaphore *semaphore; if (!_pr_initialized) _PR_ImplicitInitialization(); semaphore = PR_NEWZAP(PRSemaphore); if (NULL != semaphore) { if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR) return NULL; else return semaphore; } return NULL; }
PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name) { PRLogModuleInfo *lm; if (!_pr_initialized) _PR_ImplicitInitialization(); lm = PR_NEWZAP(PRLogModuleInfo); if (lm) { lm->name = strdup(name); lm->level = PR_LOG_NONE; lm->next = logModules; logModules = lm; _PR_SetLogModuleLevel(lm); } return lm; }
void _PR_InitMW(void) { #ifdef WINNT /* * We use NT 4's InterlockedCompareExchange() to operate * on PRMWStatus variables. */ PR_ASSERT(sizeof(LONG) == sizeof(PRMWStatus)); TimerInit(); #endif mw_lock = PR_NewLock(); PR_ASSERT(NULL != mw_lock); mw_state = PR_NEWZAP(_PRGlobalState); PR_ASSERT(NULL != mw_state); PR_INIT_CLIST(&mw_state->group_list); max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL); } /* _PR_InitMW */
PR_IMPLEMENT(PRStatus) PR_RegisterRootFinder( GCRootFinder f, char *name, void *arg) { RootFinder *rf = PR_NEWZAP(RootFinder); if (rf) { rf->func = f; rf->name = name; rf->arg = arg; LOCK_GC(); rf->next = _pr_rootFinders; _pr_rootFinders = rf; UNLOCK_GC(); return PR_SUCCESS; } return PR_FAILURE; }
PR_IMPLEMENT(PLOptState*) PL_CreateLongOptState( PRIntn argc, char **argv, const char *options, const PLLongOpt *longOpts) { PLOptState *opt = NULL; PLOptionInternal *internal; if (NULL == options) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return opt; } opt = PR_NEWZAP(PLOptState); if (NULL == opt) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return opt; } internal = PR_NEW(PLOptionInternal); if (NULL == internal) { PR_DELETE(opt); PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return NULL; } opt->option = 0; opt->value = NULL; opt->internal = internal; opt->longOption = 0; opt->longOptIndex = -1; internal->argc = argc; internal->argv = argv; internal->xargc = 0; internal->xargv = &static_Nul; internal->minus = 0; internal->options = options; internal->longOpts = longOpts; internal->endOfOpts = PR_FALSE; internal->optionsLen = PL_strlen(options); return opt; } /* PL_CreateLongOptState */
PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void) { PRMonitor *mon; int rv; if (!_pr_initialized) _PR_ImplicitInitialization(); mon = PR_NEWZAP(PRMonitor); if (mon == NULL) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return NULL; } rv = _PT_PTHREAD_MUTEX_INIT(mon->lock, _pt_mattr); PR_ASSERT(0 == rv); if (0 != rv) goto error1; _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner); rv = _PT_PTHREAD_COND_INIT(mon->entryCV, _pt_cvar_attr); PR_ASSERT(0 == rv); if (0 != rv) goto error2; rv = _PT_PTHREAD_COND_INIT(mon->waitCV, _pt_cvar_attr); PR_ASSERT(0 == rv); if (0 != rv) goto error3; mon->notifyTimes = 0; mon->entryCount = 0; mon->refCount = 1; mon->name = NULL; return mon; error3: pthread_cond_destroy(&mon->entryCV); error2: pthread_mutex_destroy(&mon->lock); error1: PR_Free(mon); PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); return NULL; } /* PR_NewMonitor */
PR_IMPLEMENT(PRLock*) PR_NewLock(void) { PRLock *lock; if (!_pr_initialized) _PR_ImplicitInitialization(); lock = PR_NEWZAP(PRLock); if (lock) { if (_PR_MD_NEW_LOCK(&lock->ilock) == PR_FAILURE) { PR_DELETE(lock); return(NULL); } PR_INIT_CLIST(&lock->links); PR_INIT_CLIST(&lock->waitQ); } return lock; }
NS_IMETHODIMP nsPop3IncomingServer::AddUidlToMark(const char *aUidl, int32_t aMark) { NS_ENSURE_ARG_POINTER(aUidl); Pop3UidlEntry *uidlEntry = PR_NEWZAP(Pop3UidlEntry); NS_ENSURE_TRUE(uidlEntry, NS_ERROR_OUT_OF_MEMORY); uidlEntry->uidl = strdup(aUidl); if (MOZ_UNLIKELY(!uidlEntry->uidl)) { PR_Free(uidlEntry); return NS_ERROR_OUT_OF_MEMORY; } uidlEntry->status = (aMark == POP3_DELETE) ? DELETE_CHAR : (aMark == POP3_FETCH_BODY) ? FETCH_BODY : KEEP; m_uidlsToMark.AppendElement(uidlEntry); return NS_OK; }
PR_IMPLEMENT(PRLock*) PR_NewLock(void) { PRIntn rv; PRLock *lock; if (!_pr_initialized) _PR_ImplicitInitialization(); lock = PR_NEWZAP(PRLock); if (lock != NULL) { rv = _PT_PTHREAD_MUTEX_INIT(lock->mutex, _pt_mattr); PR_ASSERT(0 == rv); } #if defined(DEBUG) pt_debug.locks_created += 1; #endif return lock; } /* PR_NewLock */
PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) { PRCondVar *cvar = PR_NEWZAP(PRCondVar); if (NULL != cvar) { if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) { PR_DELETE(cvar); cvar = NULL; } else { PR_INIT_CLIST(&cvar->condQ); cvar->lock = _PR_NAKED_CV_LOCK; } } return cvar; }
PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top) { PRFileDesc *fd = NULL; fd = PR_NEWZAP(PRFileDesc); if (NULL == fd) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); else { fd->methods = &pl_methods; fd->dtor = pl_FDDestructor; fd->identity = PR_IO_LAYER_HEAD; fd->higher = NULL; fd->lower = top; top->higher = fd; top->lower = NULL; } return fd; } /* PR_CreateIOLayer */
/* ** Create a new monitor. */ PR_IMPLEMENT(PRMonitor*) PR_NewMonitor() { PRMonitor *mon; PRStatus rv; if (!_pr_initialized) _PR_ImplicitInitialization(); mon = PR_NEWZAP(PRMonitor); if (mon == NULL) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return NULL; } rv = _PR_InitLock(&mon->lock); PR_ASSERT(rv == PR_SUCCESS); if (rv != PR_SUCCESS) goto error1; mon->owner = NULL; rv = _PR_InitCondVar(&mon->entryCV, &mon->lock); PR_ASSERT(rv == PR_SUCCESS); if (rv != PR_SUCCESS) goto error2; rv = _PR_InitCondVar(&mon->waitCV, &mon->lock); PR_ASSERT(rv == PR_SUCCESS); if (rv != PR_SUCCESS) goto error3; mon->notifyTimes = 0; mon->entryCount = 0; mon->name = NULL; return mon; error3: _PR_FreeCondVar(&mon->entryCV); error2: _PR_FreeLock(&mon->lock); error1: PR_Free(mon); return NULL; }