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); }
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); }
void terminateWorkerThreads(void) { VLOG(("selfserv: server_thead: waiting on stopping")); PZ_Lock(qLock); PZ_NotifyAllCondVar(jobQNotEmptyCv); while (threadCount > 0) { PZ_WaitCondVar(threadCountChangeCv, PR_INTERVAL_NO_TIMEOUT); } /* The worker threads empty the jobQ before they terminate. */ 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); }