Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(828)

Side by Side Diff: mozilla/nsprpub/pr/src/threads/combined/prucv.c

Issue 14249009: Change the NSS and NSPR source tree to the new directory structure to be (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
7 #include "primpl.h"
8 #include "prinrval.h"
9 #include "prtypes.h"
10
11 #if defined(WIN95)
12 /*
13 ** Some local variables report warnings on Win95 because the code paths
14 ** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
15 ** The pragma suppresses the warning.
16 **
17 */
18 #pragma warning(disable : 4101)
19 #endif
20
21
22 /*
23 ** Notify one thread that it has finished waiting on a condition variable
24 ** Caller must hold the _PR_CVAR_LOCK(cv)
25 */
26 PRBool _PR_NotifyThread (PRThread *thread, PRThread *me)
27 {
28 PRBool rv;
29
30 PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
31
32 _PR_THREAD_LOCK(thread);
33 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
34 if ( !_PR_IS_NATIVE_THREAD(thread) ) {
35 if (thread->wait.cvar != NULL) {
36 thread->wait.cvar = NULL;
37
38 _PR_SLEEPQ_LOCK(thread->cpu);
39 /* The notify and timeout can collide; in which case both may
40 * attempt to delete from the sleepQ; only let one do it.
41 */
42 if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
43 _PR_DEL_SLEEPQ(thread, PR_TRUE);
44 _PR_SLEEPQ_UNLOCK(thread->cpu);
45
46 if (thread->flags & _PR_SUSPENDING) {
47 /*
48 * set thread state to SUSPENDED; a Resume operation
49 * on the thread will move it to the runQ
50 */
51 thread->state = _PR_SUSPENDED;
52 _PR_MISCQ_LOCK(thread->cpu);
53 _PR_ADD_SUSPENDQ(thread, thread->cpu);
54 _PR_MISCQ_UNLOCK(thread->cpu);
55 _PR_THREAD_UNLOCK(thread);
56 } else {
57 /* Make thread runnable */
58 thread->state = _PR_RUNNABLE;
59 _PR_THREAD_UNLOCK(thread);
60
61 _PR_AddThreadToRunQ(me, thread);
62 _PR_MD_WAKEUP_WAITER(thread);
63 }
64
65 rv = PR_TRUE;
66 } else {
67 /* Thread has already been notified */
68 _PR_THREAD_UNLOCK(thread);
69 rv = PR_FALSE;
70 }
71 } else { /* If the thread is a native thread */
72 if (thread->wait.cvar) {
73 thread->wait.cvar = NULL;
74
75 if (thread->flags & _PR_SUSPENDING) {
76 /*
77 * set thread state to SUSPENDED; a Resume operation
78 * on the thread will enable the thread to run
79 */
80 thread->state = _PR_SUSPENDED;
81 } else
82 thread->state = _PR_RUNNING;
83 _PR_THREAD_UNLOCK(thread);
84 _PR_MD_WAKEUP_WAITER(thread);
85 rv = PR_TRUE;
86 } else {
87 _PR_THREAD_UNLOCK(thread);
88 rv = PR_FALSE;
89 }
90 }
91
92 return rv;
93 }
94
95 /*
96 * Notify thread waiting on cvar; called when thread is interrupted
97 * The thread lock is held on entry and released before return
98 */
99 void _PR_NotifyLockedThread (PRThread *thread)
100 {
101 PRThread *me = _PR_MD_CURRENT_THREAD();
102 PRCondVar *cvar;
103 PRThreadPriority pri;
104
105 if ( !_PR_IS_NATIVE_THREAD(me))
106 PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
107
108 cvar = thread->wait.cvar;
109 thread->wait.cvar = NULL;
110 _PR_THREAD_UNLOCK(thread);
111
112 _PR_CVAR_LOCK(cvar);
113 _PR_THREAD_LOCK(thread);
114
115 if (!_PR_IS_NATIVE_THREAD(thread)) {
116 _PR_SLEEPQ_LOCK(thread->cpu);
117 /* The notify and timeout can collide; in which case both may
118 * attempt to delete from the sleepQ; only let one do it.
119 */
120 if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
121 _PR_DEL_SLEEPQ(thread, PR_TRUE);
122 _PR_SLEEPQ_UNLOCK(thread->cpu);
123
124 /* Make thread runnable */
125 pri = thread->priority;
126 thread->state = _PR_RUNNABLE;
127
128 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
129
130 _PR_AddThreadToRunQ(me, thread);
131 _PR_THREAD_UNLOCK(thread);
132
133 _PR_MD_WAKEUP_WAITER(thread);
134 } else {
135 if (thread->flags & _PR_SUSPENDING) {
136 /*
137 * set thread state to SUSPENDED; a Resume operation
138 * on the thread will enable the thread to run
139 */
140 thread->state = _PR_SUSPENDED;
141 } else
142 thread->state = _PR_RUNNING;
143 _PR_THREAD_UNLOCK(thread);
144 _PR_MD_WAKEUP_WAITER(thread);
145 }
146
147 _PR_CVAR_UNLOCK(cvar);
148 return;
149 }
150
151 /*
152 ** Make the given thread wait for the given condition variable
153 */
154 PRStatus _PR_WaitCondVar(
155 PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
156 {
157 PRIntn is;
158 PRStatus rv = PR_SUCCESS;
159
160 PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
161 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
162
163 #ifdef _PR_GLOBAL_THREADS_ONLY
164 if (_PR_PENDING_INTERRUPT(thread)) {
165 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
166 thread->flags &= ~_PR_INTERRUPT;
167 return PR_FAILURE;
168 }
169
170 thread->wait.cvar = cvar;
171 lock->owner = NULL;
172 _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout);
173 thread->wait.cvar = NULL;
174 lock->owner = thread;
175 if (_PR_PENDING_INTERRUPT(thread)) {
176 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
177 thread->flags &= ~_PR_INTERRUPT;
178 return PR_FAILURE;
179 }
180
181 return PR_SUCCESS;
182 #else /* _PR_GLOBAL_THREADS_ONLY */
183
184 if ( !_PR_IS_NATIVE_THREAD(thread))
185 _PR_INTSOFF(is);
186
187 _PR_CVAR_LOCK(cvar);
188 _PR_THREAD_LOCK(thread);
189
190 if (_PR_PENDING_INTERRUPT(thread)) {
191 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
192 thread->flags &= ~_PR_INTERRUPT;
193 _PR_CVAR_UNLOCK(cvar);
194 _PR_THREAD_UNLOCK(thread);
195 if ( !_PR_IS_NATIVE_THREAD(thread))
196 _PR_INTSON(is);
197 return PR_FAILURE;
198 }
199
200 thread->state = _PR_COND_WAIT;
201 thread->wait.cvar = cvar;
202
203 /*
204 ** Put the caller thread on the condition variable's wait Q
205 */
206 PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ);
207
208 /* Note- for global scope threads, we don't put them on the
209 * global sleepQ, so each global thread must put itself
210 * to sleep only for the time it wants to.
211 */
212 if ( !_PR_IS_NATIVE_THREAD(thread) ) {
213 _PR_SLEEPQ_LOCK(thread->cpu);
214 _PR_ADD_SLEEPQ(thread, timeout);
215 _PR_SLEEPQ_UNLOCK(thread->cpu);
216 }
217 _PR_CVAR_UNLOCK(cvar);
218 _PR_THREAD_UNLOCK(thread);
219
220 /*
221 ** Release lock protecting the condition variable and thereby giving time
222 ** to the next thread which can potentially notify on the condition variable
223 */
224 PR_Unlock(lock);
225
226 PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
227 ("PR_Wait: cvar=%p waiting for %d", cvar, timeout));
228
229 rv = _PR_MD_WAIT(thread, timeout);
230
231 _PR_CVAR_LOCK(cvar);
232 PR_REMOVE_LINK(&thread->waitQLinks);
233 _PR_CVAR_UNLOCK(cvar);
234
235 PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
236 ("PR_Wait: cvar=%p done waiting", cvar));
237
238 if ( !_PR_IS_NATIVE_THREAD(thread))
239 _PR_INTSON(is);
240
241 /* Acquire lock again that we had just relinquished */
242 PR_Lock(lock);
243
244 if (_PR_PENDING_INTERRUPT(thread)) {
245 PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
246 thread->flags &= ~_PR_INTERRUPT;
247 return PR_FAILURE;
248 }
249
250 return rv;
251 #endif /* _PR_GLOBAL_THREADS_ONLY */
252 }
253
254 void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me)
255 {
256 #ifdef _PR_GLOBAL_THREADS_ONLY
257 _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock);
258 #else /* _PR_GLOBAL_THREADS_ONLY */
259
260 PRCList *q;
261 PRIntn is;
262
263 if ( !_PR_IS_NATIVE_THREAD(me))
264 _PR_INTSOFF(is);
265 PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
266
267 _PR_CVAR_LOCK(cvar);
268 q = cvar->condQ.next;
269 while (q != &cvar->condQ) {
270 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));
271 if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) {
272 if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)
273 break;
274 }
275 q = q->next;
276 }
277 _PR_CVAR_UNLOCK(cvar);
278
279 if ( !_PR_IS_NATIVE_THREAD(me))
280 _PR_INTSON(is);
281
282 #endif /* _PR_GLOBAL_THREADS_ONLY */
283 }
284
285 /*
286 ** Cndition variable debugging log info.
287 */
288 PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen)
289 {
290 PRUint32 nb;
291
292 if (cvar->lock->owner) {
293 nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]",
294 cvar, cvar->lock->owner->id, cvar->lock->owner);
295 } else {
296 nb = PR_snprintf(buf, buflen, "[%p]", cvar);
297 }
298 return nb;
299 }
300
301 /*
302 ** Expire condition variable waits that are ready to expire. "now" is the curren t
303 ** time.
304 */
305 void _PR_ClockInterrupt(void)
306 {
307 PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
308 _PRCPU *cpu = me->cpu;
309 PRIntervalTime elapsed, now;
310
311 PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
312 /* Figure out how much time elapsed since the last clock tick */
313 now = PR_IntervalNow();
314 elapsed = now - cpu->last_clock;
315 cpu->last_clock = now;
316
317 PR_LOG(_pr_clock_lm, PR_LOG_MAX,
318 ("ExpireWaits: elapsed=%lld usec", elapsed));
319
320 while(1) {
321 _PR_SLEEPQ_LOCK(cpu);
322 if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) {
323 _PR_SLEEPQ_UNLOCK(cpu);
324 break;
325 }
326
327 thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next);
328 PR_ASSERT(thread->cpu == cpu);
329
330 if (elapsed < thread->sleep) {
331 thread->sleep -= elapsed;
332 _PR_SLEEPQMAX(thread->cpu) -= elapsed;
333 _PR_SLEEPQ_UNLOCK(cpu);
334 break;
335 }
336 _PR_SLEEPQ_UNLOCK(cpu);
337
338 PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
339
340 _PR_THREAD_LOCK(thread);
341
342 if (thread->cpu != cpu) {
343 /*
344 ** The thread was switched to another CPU
345 ** between the time we unlocked the sleep
346 ** queue and the time we acquired the thread
347 ** lock, so it is none of our business now.
348 */
349 _PR_THREAD_UNLOCK(thread);
350 continue;
351 }
352
353 /*
354 ** Consume this sleeper's amount of elapsed time from the elapsed
355 ** time value. The next remaining piece of elapsed time will be
356 ** available for the next sleeping thread's timer.
357 */
358 _PR_SLEEPQ_LOCK(cpu);
359 PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ));
360 if (thread->flags & _PR_ON_SLEEPQ) {
361 _PR_DEL_SLEEPQ(thread, PR_FALSE);
362 elapsed -= thread->sleep;
363 _PR_SLEEPQ_UNLOCK(cpu);
364 } else {
365 /* Thread was already handled; Go get another one */
366 _PR_SLEEPQ_UNLOCK(cpu);
367 _PR_THREAD_UNLOCK(thread);
368 continue;
369 }
370
371 /* Notify the thread waiting on the condition variable */
372 if (thread->flags & _PR_SUSPENDING) {
373 PR_ASSERT((thread->state == _PR_IO_WAIT) ||
374 (thread->state == _PR_COND_WAIT));
375 /*
376 ** Thread is suspended and its condition timeout
377 ** expired. Transfer thread from sleepQ to suspendQ.
378 */
379 thread->wait.cvar = NULL;
380 _PR_MISCQ_LOCK(cpu);
381 thread->state = _PR_SUSPENDED;
382 _PR_ADD_SUSPENDQ(thread, cpu);
383 _PR_MISCQ_UNLOCK(cpu);
384 } else {
385 if (thread->wait.cvar) {
386 PRThreadPriority pri;
387
388 /* Do work very similar to what _PR_NotifyThread does */
389 PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
390
391 /* Make thread runnable */
392 pri = thread->priority;
393 thread->state = _PR_RUNNABLE;
394 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
395
396 PR_ASSERT(thread->cpu == cpu);
397 _PR_RUNQ_LOCK(cpu);
398 _PR_ADD_RUNQ(thread, cpu, pri);
399 _PR_RUNQ_UNLOCK(cpu);
400
401 if (pri > me->priority)
402 _PR_SET_RESCHED_FLAG();
403
404 thread->wait.cvar = NULL;
405
406 _PR_MD_WAKEUP_WAITER(thread);
407
408 } else if (thread->io_pending == PR_TRUE) {
409 /* Need to put IO sleeper back on runq */
410 int pri = thread->priority;
411
412 thread->io_suspended = PR_TRUE;
413 #ifdef WINNT
414 /*
415 * For NT, record the cpu on which I/O was issue d
416 * I/O cancellation is done on the same cpu
417 */
418 thread->md.thr_bound_cpu = cpu;
419 #endif
420
421 PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
422 PR_ASSERT(thread->cpu == cpu);
423 thread->state = _PR_RUNNABLE;
424 _PR_RUNQ_LOCK(cpu);
425 _PR_ADD_RUNQ(thread, cpu, pri);
426 _PR_RUNQ_UNLOCK(cpu);
427 }
428 }
429 _PR_THREAD_UNLOCK(thread);
430 }
431 }
432
433 /************************************************************************/
434
435 /*
436 ** Create a new condition variable.
437 ** "lock" is the lock to use with the condition variable.
438 **
439 ** Condition variables are synchronization objects that threads can use
440 ** to wait for some condition to occur.
441 **
442 ** This may fail if memory is tight or if some operating system resource
443 ** is low.
444 */
445 PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
446 {
447 PRCondVar *cvar;
448
449 PR_ASSERT(lock != NULL);
450
451 cvar = PR_NEWZAP(PRCondVar);
452 if (cvar) {
453 #ifdef _PR_GLOBAL_THREADS_ONLY
454 if(_PR_MD_NEW_CV(&cvar->md)) {
455 PR_DELETE(cvar);
456 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
457 return NULL;
458 }
459 #endif
460 if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) {
461 PR_DELETE(cvar);
462 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
463 return NULL;
464 }
465 cvar->lock = lock;
466 PR_INIT_CLIST(&cvar->condQ);
467
468 } else {
469 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
470 }
471 return cvar;
472 }
473
474 /*
475 ** Destroy a condition variable. There must be no thread
476 ** waiting on the condvar. The caller is responsible for guaranteeing
477 ** that the condvar is no longer in use.
478 **
479 */
480 PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
481 {
482 PR_ASSERT(cvar->condQ.next == &cvar->condQ);
483
484 #ifdef _PR_GLOBAL_THREADS_ONLY
485 _PR_MD_FREE_CV(&cvar->md);
486 #endif
487 _PR_MD_FREE_LOCK(&(cvar->ilock));
488
489 PR_DELETE(cvar);
490 }
491
492 /*
493 ** Wait for a notify on the condition variable. Sleep for "tiemout" amount
494 ** of ticks (if "timeout" is zero then the sleep is indefinite). While
495 ** the thread is waiting it unlocks lock. When the wait has
496 ** finished the thread regains control of the condition variable after
497 ** locking the associated lock.
498 **
499 ** The thread waiting on the condvar will be resumed when the condvar is
500 ** notified (assuming the thread is the next in line to receive the
501 ** notify) or when the timeout elapses.
502 **
503 ** Returns PR_FAILURE if the caller has not locked the lock associated
504 ** with the condition variable or the thread has been interrupted.
505 */
506 extern PRThread *suspendAllThread;
507 PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
508 {
509 PRThread *me = _PR_MD_CURRENT_THREAD();
510
511 PR_ASSERT(cvar->lock->owner == me);
512 PR_ASSERT(me != suspendAllThread);
513 if (cvar->lock->owner != me) return PR_FAILURE;
514
515 return _PR_WaitCondVar(me, cvar, cvar->lock, timeout);
516 }
517
518 /*
519 ** Notify the highest priority thread waiting on the condition
520 ** variable. If a thread is waiting on the condition variable (using
521 ** PR_Wait) then it is awakened and begins waiting on the lock.
522 */
523 PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar)
524 {
525 PRThread *me = _PR_MD_CURRENT_THREAD();
526
527 PR_ASSERT(cvar->lock->owner == me);
528 PR_ASSERT(me != suspendAllThread);
529 if (cvar->lock->owner != me) return PR_FAILURE;
530
531 _PR_NotifyCondVar(cvar, me);
532 return PR_SUCCESS;
533 }
534
535 /*
536 ** Notify all of the threads waiting on the condition variable. All of
537 ** threads are notified in turn. The highest priority thread will
538 ** probably acquire the lock.
539 */
540 PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
541 {
542 PRCList *q;
543 PRIntn is;
544 PRThread *me = _PR_MD_CURRENT_THREAD();
545
546 PR_ASSERT(cvar->lock->owner == me);
547 if (cvar->lock->owner != me) return PR_FAILURE;
548
549 #ifdef _PR_GLOBAL_THREADS_ONLY
550 _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock);
551 return PR_SUCCESS;
552 #else /* _PR_GLOBAL_THREADS_ONLY */
553 if ( !_PR_IS_NATIVE_THREAD(me))
554 _PR_INTSOFF(is);
555 _PR_CVAR_LOCK(cvar);
556 q = cvar->condQ.next;
557 while (q != &cvar->condQ) {
558 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)) ;
559 _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
560 q = q->next;
561 }
562 _PR_CVAR_UNLOCK(cvar);
563 if (!_PR_IS_NATIVE_THREAD(me))
564 _PR_INTSON(is);
565
566 return PR_SUCCESS;
567 #endif /* _PR_GLOBAL_THREADS_ONLY */
568 }
569
570
571 /*********************************************************************/
572 /*********************************************************************/
573 /********************ROUTINES FOR DCE EMULATION***********************/
574 /*********************************************************************/
575 /*********************************************************************/
576 #include "prpdce.h"
577
578 PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
579 {
580 PRCondVar *cvar = PR_NEWZAP(PRCondVar);
581 if (NULL != cvar)
582 {
583 if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE)
584 {
585 PR_DELETE(cvar); cvar = NULL;
586 }
587 else
588 {
589 PR_INIT_CLIST(&cvar->condQ);
590 cvar->lock = _PR_NAKED_CV_LOCK;
591 }
592
593 }
594 return cvar;
595 }
596
597 PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar)
598 {
599 PR_ASSERT(cvar->condQ.next == &cvar->condQ);
600 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
601
602 _PR_MD_FREE_LOCK(&(cvar->ilock));
603
604 PR_DELETE(cvar);
605 }
606
607 PR_IMPLEMENT(PRStatus) PRP_NakedWait(
608 PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
609 {
610 PRThread *me = _PR_MD_CURRENT_THREAD();
611 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
612 return _PR_WaitCondVar(me, cvar, lock, timeout);
613 } /* PRP_NakedWait */
614
615 PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar)
616 {
617 PRThread *me = _PR_MD_CURRENT_THREAD();
618 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
619
620 _PR_NotifyCondVar(cvar, me);
621
622 return PR_SUCCESS;
623 } /* PRP_NakedNotify */
624
625 PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
626 {
627 PRCList *q;
628 PRIntn is;
629 PRThread *me = _PR_MD_CURRENT_THREAD();
630 PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
631
632 if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
633 _PR_MD_LOCK( &(cvar->ilock) );
634 q = cvar->condQ.next;
635 while (q != &cvar->condQ) {
636 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)) ;
637 _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
638 q = q->next;
639 }
640 _PR_MD_UNLOCK( &(cvar->ilock) );
641 if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
642
643 return PR_SUCCESS;
644 } /* PRP_NakedBroadcast */
645
OLDNEW
« no previous file with comments | « mozilla/nsprpub/pr/src/threads/combined/prucpu.c ('k') | mozilla/nsprpub/pr/src/threads/combined/prulock.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698