static PRBool AlarmFn2(PRAlarmID *id, void *clientData, PRUint32 late) { #if defined(XP_MAC) #pragma unused (id) #endif PRBool keepGoing; PRStatus rv = PR_SUCCESS; AlarmData *ad = (AlarmData*)clientData; PRIntervalTime interval, now = PR_IntervalNow(); PR_Lock(ad->ml); ad->times += 1; keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ? PR_TRUE : PR_FALSE; interval = (ad->period + ad->rate - 1) / ad->rate; if (!late && (interval > 10)) { interval &= (now & 0x03) + 1; PR_WaitCondVar(ad->cv, interval); } if (!keepGoing) rv = PR_NotifyCondVar(ad->cv); PR_Unlock(ad->ml); if (rv != PR_SUCCESS) failed_already=1;; return keepGoing; } /* AlarmFn2 */
/* Thread that gets notified; no other threads use the same condvar */ void PR_CALLBACK PrivateCondVarThread(void *_info) { threadinfo *info = (threadinfo *)_info; PRInt32 index; for (index=0; index<info->loops; index++) { PR_Lock(info->lock); if (*info->tcount == 0) { DPRINTF(("PrivateCondVarThread: thread 0x%lx waiting on cvar = 0x%lx\n", PR_GetCurrentThread(), info->cvar)); PR_WaitCondVar(info->cvar, info->timeout); } #if 0 printf("solo thread %ld notified in loop %ld\n", info->id, index); #endif (*info->tcount)--; PR_Unlock(info->lock); PR_Lock(info->exitlock); (*info->exitcount)++; PR_NotifyCondVar(info->exitcvar); DPRINTF(("PrivateCondVarThread: thread 0x%lx notified exitcvar = 0x%lx cnt = %ld\n", PR_GetCurrentThread(), info->exitcvar,(*info->exitcount))); PR_Unlock(info->exitlock); } #if 0 printf("solo thread %ld terminating\n", info->id); #endif }
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 */
/* ** Notify the highest priority thread waiting on the condition ** variable. If a thread is waiting on the condition variable (using ** PR_Wait) then it is awakened and begins waiting on the monitor's lock. */ PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon) { PRThread *me = _PR_MD_CURRENT_THREAD(); if (mon->cvar->lock->owner != me) return PR_FAILURE; PR_NotifyCondVar(mon->cvar); return PR_SUCCESS; }
/* Thread that gets notified; many threads share the same condvar */ void PR_CALLBACK SharedCondVarThread(void *_info) { threadinfo *info = (threadinfo *)_info; PRInt32 index; for (index=0; index<info->loops; index++) { PR_Lock(info->lock); if (*info->tcount == 0) PR_WaitCondVar(info->cvar, info->timeout); #if 0 printf("shared thread %ld notified in loop %ld\n", info->id, index); #endif (*info->tcount)--; PR_Unlock(info->lock); PR_Lock(info->exitlock); (*info->exitcount)++; PR_NotifyCondVar(info->exitcvar); PR_Unlock(info->exitlock); } #if 0 printf("shared thread %ld terminating\n", info->id); #endif }
//static void XPCJSRuntime::WatchdogMain(void *arg) { XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg); // Lock lasts until we return AutoLockJSGC lock(self->mJSRuntime); PRIntervalTime sleepInterval; while (self->mWatchdogThread) { // Sleep only 1 second if recently (or currently) active; otherwise, hibernate if (self->mLastActiveTime == -1 || PR_Now() - self->mLastActiveTime <= 2*PR_USEC_PER_SEC) sleepInterval = PR_TicksPerSecond(); else { sleepInterval = PR_INTERVAL_NO_TIMEOUT; self->mWatchdogHibernating = PR_TRUE; } #ifdef DEBUG PRStatus status = #endif PR_WaitCondVar(self->mWatchdogWakeup, sleepInterval); JS_ASSERT(status == PR_SUCCESS); JSContext* cx = nsnull; while((cx = js_NextActiveContext(self->mJSRuntime, cx))) { JS_TriggerOperationCallback(cx); } } /* Wake up the main thread waiting for the watchdog to terminate. */ PR_NotifyCondVar(self->mWatchdogWakeup); }
/* ** Exit the lock associated with the monitor once. */ PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon) { PRThread *me = _PR_MD_CURRENT_THREAD(); PRStatus rv; PR_ASSERT(mon != NULL); PR_Lock(&mon->lock); /* the entries should be > 0 and we'd better be the owner */ PR_ASSERT(mon->entryCount > 0); PR_ASSERT(mon->owner == me); if (mon->entryCount == 0 || mon->owner != me) { rv = PR_Unlock(&mon->lock); PR_ASSERT(rv == PR_SUCCESS); return PR_FAILURE; } mon->entryCount -= 1; /* reduce by one */ if (mon->entryCount == 0) { /* and if it transitioned to zero - notify an entry waiter */ /* make the owner unknown */ mon->owner = NULL; if (mon->notifyTimes != 0) { _PR_PostNotifiesFromMonitor(&mon->waitCV, mon->notifyTimes); mon->notifyTimes = 0; } rv = PR_NotifyCondVar(&mon->entryCV); PR_ASSERT(rv == PR_SUCCESS); } rv = PR_Unlock(&mon->lock); PR_ASSERT(rv == PR_SUCCESS); return PR_SUCCESS; }
static void AcceptThread(void *arg) { PRIntn bytesRead; char dataBuf[ACCEPT_READ_BUFSIZE]; PRFileDesc *arSock; PRNetAddr *arAddr; bytesRead = PR_AcceptRead( listenSock, &arSock, &arAddr, dataBuf, ACCEPT_READ_DATASIZE, PR_SecondsToInterval(1)); if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR ) if ( debug ) printf("AcceptRead timed out\n"); else if ( debug ) printf("Oops! read: %d, error: %d\n", bytesRead, PR_GetError()); while( state != AllDone ) { PR_Lock( ml ); while( state != RunAcceptRead ) PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); if ( ++iCounter >= jitter ) state = AllDone; else state = RunJitter; if ( verbose ) printf("."); PR_NotifyCondVar( cv ); PR_Unlock( ml ); PR_Write( file1, ".", 1 ); } return; } /* end AcceptThread() */
//static void XPCJSRuntime::WatchdogMain(void *arg) { XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg); // Lock lasts until we return AutoLockJSGC lock(self->mJSRuntime); while (self->mWatchdogThread) { #ifdef DEBUG PRStatus status = #endif PR_WaitCondVar(self->mWatchdogWakeup, PR_TicksPerSecond()); JS_ASSERT(status == PR_SUCCESS); JSContext* cx = nsnull; while((cx = js_NextActiveContext(self->mJSRuntime, cx))) { JS_TriggerOperationCallback(cx); } } /* Wake up the main thread waiting for the watchdog to terminate. */ PR_NotifyCondVar(self->mWatchdogWakeup); }
static TimerEvent *CreateTimer( PRIntervalTime timeout, void (*func)(void *), void *arg) { TimerEvent *timer; PRCList *links, *tail; TimerEvent *elem; timer = PR_NEW(TimerEvent); if (NULL == timer) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return timer; } timer->absolute = PR_IntervalNow() + timeout; timer->func = func; timer->arg = arg; timer->ref_count = 2; PR_Lock(tm_vars.ml); tail = links = PR_LIST_TAIL(&tm_vars.timer_queue); while (links->prev != tail) { elem = TIMER_EVENT_PTR(links); if ((PRInt32)(timer->absolute - elem->absolute) >= 0) { break; } links = links->prev; } PR_INSERT_AFTER(&timer->links, links); PR_NotifyCondVar(tm_vars.new_timer); PR_Unlock(tm_vars.ml); return timer; }
static void notify_timerq(PRThreadPool *tp) { /* * wakeup the timer thread(s) */ PR_NotifyCondVar(tp->timerq.cv); }
void Resolver :: started() { PR_Lock(dnslock); awake = PR_TRUE; ok = PR_TRUE; // successful start, async DNS is now enabled PR_NotifyCondVar(initcvar); PR_Unlock(dnslock); }
void Resolver :: error() { PR_Lock(dnslock); awake = PR_TRUE; ok = PR_FALSE; // couldn't initialize resolver PR_NotifyCondVar(initcvar); PR_Unlock(dnslock); }
void DNSSession :: error() { // set status PR_Lock(lock); status = DNS_ERROR; awake = PR_TRUE; PR_NotifyCondVar(cvar); PR_Unlock(lock); }
void DNSSession :: expire() { // set status PR_Lock(lock); status = DNS_TIMED_OUT; awake = PR_TRUE; PR_NotifyCondVar(cvar); PR_Unlock(lock); }
void DNSSession :: complete() { // set status PR_Lock(lock); status = DNS_COMPLETED; awake = PR_TRUE; PR_NotifyCondVar(cvar); PR_Unlock(lock); }
void LdapSessionPool::add_free_session(LdapSession *session) { _active_list.Delete (session); _free_list.Append (session); if (_waiters) { // tell the waiters that we might have something for them PR_NotifyCondVar (_cvar); } }
PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *semaphore) { static PRBool unwarned = PR_TRUE; if (unwarned) unwarned = _PR_Obsolete( "PR_PostSem", "locks & condition variables"); PR_Lock(semaphore->cvar->lock); PR_NotifyCondVar(semaphore->cvar); semaphore->count += 1; PR_Unlock(semaphore->cvar->lock); } /* PR_PostSem */
/* --- Server state functions --------------------------------------------- */ void SetServerState(char *waiter, PRInt32 state) { PR_Lock(ServerStateCVLock); ServerState = state; PR_NotifyCondVar(ServerStateCV); if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state); PR_Unlock(ServerStateCVLock); }
/* ** This routine increments the counter value of the semaphore. If other threads ** are blocked for the semaphore, then the scheduler will determine which ONE ** thread will be unblocked. */ PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *sem) { #ifdef HAVE_CVAR_BUILT_ON_SEM _PR_MD_POST_SEM(&sem->md); #else PR_Lock(sem->cvar->lock); if (sem->waiters) PR_NotifyCondVar(sem->cvar); sem->count++; PR_Unlock(sem->cvar->lock); #endif }
int /* returns count */ lockedVars_AddToCount(lockedVars * lv, int addend) { int rv; PR_Lock(lv->lock); rv = lv->count += addend; if (rv <= 0) { PR_NotifyCondVar(lv->condVar); } PR_Unlock(lv->lock); return rv; }
void JSBackgroundThread::cancel() { PR_Lock(lock); if (shutdown) { PR_Unlock(lock); return; } shutdown = true; PR_NotifyCondVar(wakeup); PR_Unlock(lock); PR_JoinThread(thread); }
static PRBool AlarmFn1(PRAlarmID *id, void *clientData, PRUint32 late) { PRStatus rv = PR_SUCCESS; PRBool keepGoing, resetAlarm; PRIntervalTime interval, now = PR_IntervalNow(); AlarmData *ad = (AlarmData*)clientData; PR_Lock(ad->ml); ad->late += late; ad->times += 1; keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ? PR_TRUE : PR_FALSE; if (!keepGoing) rv = PR_NotifyCondVar(ad->cv); resetAlarm = ((ad->times % 31) == 0) ? PR_TRUE : PR_FALSE; interval = (ad->period + ad->rate - 1) / ad->rate; if (!late && (interval > 10)) { interval &= (now & 0x03) + 1; PR_WaitCondVar(ad->cv, interval); } PR_Unlock(ad->ml); if (rv != PR_SUCCESS) { if (!debug_mode) failed_already=1; else printf("AlarmFn: notify status: FAIL\n"); } if (resetAlarm) { ad->rate += 3; ad->late = ad->times = 0; if (PR_ResetAlarm(id, ad->period, ad->rate) != PR_SUCCESS) { if (!debug_mode) failed_already=1; else printf("AlarmFn: Resetting alarm status: FAIL\n"); keepGoing = PR_FALSE; } } return keepGoing; } /* AlarmFn1 */
/* * 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 }
/* ** PutCBData puts new data on the queue. If the queue is full, it waits ** until there is room. */ static void PutCBData(CircBuf *cbp, void *data) { PR_Lock(cbp->bufLock); /* wait while the buffer is full */ while (cbp->numFull == kQSIZE) PR_WaitCondVar(cbp->notFull,PR_INTERVAL_NO_TIMEOUT); cbp->data[(cbp->startIdx + cbp->numFull) % kQSIZE] = data; cbp->numFull += 1; /* let a waiting reader know that there is data */ PR_NotifyCondVar(cbp->notEmpty); PR_Unlock(cbp->bufLock); }
static void Notifier(void *arg) { NotifyData *notifyData = (NotifyData*)arg; PR_Lock(notifyData->ml); while (notifyData->counter > 0) { while (!notifyData->pending) PR_WaitCondVar(notifyData->child, PR_INTERVAL_NO_TIMEOUT); notifyData->counter -= 1; notifyData->pending = PR_FALSE; PR_NotifyCondVar(notifyData->parent); } PR_Unlock(notifyData->ml); } /* Notifier */
// ViEExternalRenderer Callback. Process every incoming frame here. int MediaEngineWebRTCVideoSource::DeliverFrame( unsigned char* buffer, int size, uint32_t time_stamp, int64_t render_time) { ReentrantMonitorAutoEnter enter(mMonitor); if (mInSnapshotMode) { // Set the condition variable to false and notify Snapshot(). PR_Lock(mSnapshotLock); mInSnapshotMode = false; PR_NotifyCondVar(mSnapshotCondVar); PR_Unlock(mSnapshotLock); return 0; } // Check for proper state. if (mState != kStarted) { return 0; } // Create a video frame and append it to the track. layers::Image::Format format = layers::Image::PLANAR_YCBCR; nsRefPtr<layers::Image> image = mImageContainer->CreateImage(&format, 1); layers::PlanarYCbCrImage* videoImage = static_cast<layers::PlanarYCbCrImage*>(image.get()); PRUint8* frame = static_cast<PRUint8*> (buffer); const PRUint8 lumaBpp = 8; const PRUint8 chromaBpp = 4; layers::PlanarYCbCrImage::Data data; data.mYChannel = frame; data.mYSize = gfxIntSize(mWidth, mHeight); data.mYStride = mWidth * lumaBpp/ 8; data.mCbCrStride = mWidth * chromaBpp / 8; data.mCbChannel = frame + mHeight * data.mYStride; data.mCrChannel = data.mCbChannel + mHeight * data.mCbCrStride / 2; data.mCbCrSize = gfxIntSize(mWidth/ 2, mHeight/ 2); data.mPicX = 0; data.mPicY = 0; data.mPicSize = gfxIntSize(mWidth, mHeight); data.mStereoMode = layers::STEREO_MODE_MONO; videoImage->SetData(data); VideoSegment segment; segment.AppendFrame(image.forget(), 1, gfxIntSize(mWidth, mHeight)); mSource->AppendToTrack(mTrackID, &(segment)); return 0; }
nsresult TimerThread::AddTimer(nsTimerImpl *aTimer) { nsAutoLock lock(mLock); // Add the timer to our list. PRInt32 i = AddTimerInternal(aTimer); if (i < 0) return NS_ERROR_OUT_OF_MEMORY; // Awaken the timer thread. if (mCondVar && mWaiting && i == 0) PR_NotifyCondVar(mCondVar); return NS_OK; }
int referint_postop_close( Slapi_PBlock *pb) { /* signal the thread to exit */ if (NULL != keeprunning_mutex) { PR_Lock(keeprunning_mutex); keeprunning=0; if (NULL != keeprunning_cv) { PR_NotifyCondVar(keeprunning_cv); } PR_Unlock(keeprunning_mutex); } refint_started = 0; return(0); }
static void JitterThread(void *arg) { while( state != AllDone ) { PR_Lock( ml ); while( state != RunJitter && state != AllDone ) PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT ); if ( state != AllDone) state = RunAcceptRead; if ( verbose ) printf("+"); PR_NotifyCondVar( cv ); PR_Unlock( ml ); PR_Write( file1, "+", 1 ); } return; } /* end Goofy() */