OLD | NEW |
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 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 | 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 | 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/. */ | 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | 5 |
6 | 6 |
7 #include "primpl.h" | 7 #include "primpl.h" |
8 #include "prinrval.h" | 8 #include "prinrval.h" |
9 #include "prtypes.h" | 9 #include "prtypes.h" |
10 | 10 |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 ** Condition variables are synchronization objects that threads can use | 439 ** Condition variables are synchronization objects that threads can use |
440 ** to wait for some condition to occur. | 440 ** to wait for some condition to occur. |
441 ** | 441 ** |
442 ** This may fail if memory is tight or if some operating system resource | 442 ** This may fail if memory is tight or if some operating system resource |
443 ** is low. | 443 ** is low. |
444 */ | 444 */ |
445 PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) | 445 PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) |
446 { | 446 { |
447 PRCondVar *cvar; | 447 PRCondVar *cvar; |
448 | 448 |
449 PR_ASSERT(lock != NULL); | |
450 | |
451 cvar = PR_NEWZAP(PRCondVar); | 449 cvar = PR_NEWZAP(PRCondVar); |
452 if (cvar) { | 450 if (cvar) { |
453 #ifdef _PR_GLOBAL_THREADS_ONLY | 451 if (_PR_InitCondVar(cvar, lock) != PR_SUCCESS) { |
454 » if(_PR_MD_NEW_CV(&cvar->md)) { | 452 PR_DELETE(cvar); |
455 » » PR_DELETE(cvar); | 453 return NULL; |
456 » » PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); | 454 } |
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 { | 455 } else { |
469 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); | 456 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); |
470 } | 457 } |
471 return cvar; | 458 return cvar; |
472 } | 459 } |
473 | 460 |
| 461 PRStatus _PR_InitCondVar(PRCondVar *cvar, PRLock *lock) |
| 462 { |
| 463 PR_ASSERT(lock != NULL); |
| 464 |
| 465 #ifdef _PR_GLOBAL_THREADS_ONLY |
| 466 if(_PR_MD_NEW_CV(&cvar->md)) { |
| 467 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); |
| 468 return PR_FAILURE; |
| 469 } |
| 470 #endif |
| 471 if (_PR_MD_NEW_LOCK(&(cvar->ilock)) != PR_SUCCESS) { |
| 472 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); |
| 473 return PR_FAILURE; |
| 474 } |
| 475 cvar->lock = lock; |
| 476 PR_INIT_CLIST(&cvar->condQ); |
| 477 return PR_SUCCESS; |
| 478 } |
| 479 |
474 /* | 480 /* |
475 ** Destroy a condition variable. There must be no thread | 481 ** Destroy a condition variable. There must be no thread |
476 ** waiting on the condvar. The caller is responsible for guaranteeing | 482 ** waiting on the condvar. The caller is responsible for guaranteeing |
477 ** that the condvar is no longer in use. | 483 ** that the condvar is no longer in use. |
478 ** | 484 ** |
479 */ | 485 */ |
480 PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) | 486 PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) |
481 { | 487 { |
| 488 _PR_FreeCondVar(cvar); |
| 489 PR_DELETE(cvar); |
| 490 } |
| 491 |
| 492 void _PR_FreeCondVar(PRCondVar *cvar) |
| 493 { |
482 PR_ASSERT(cvar->condQ.next == &cvar->condQ); | 494 PR_ASSERT(cvar->condQ.next == &cvar->condQ); |
483 | 495 |
484 #ifdef _PR_GLOBAL_THREADS_ONLY | 496 #ifdef _PR_GLOBAL_THREADS_ONLY |
485 _PR_MD_FREE_CV(&cvar->md); | 497 _PR_MD_FREE_CV(&cvar->md); |
486 #endif | 498 #endif |
487 _PR_MD_FREE_LOCK(&(cvar->ilock)); | 499 _PR_MD_FREE_LOCK(&(cvar->ilock)); |
488 | |
489 PR_DELETE(cvar); | |
490 } | 500 } |
491 | 501 |
492 /* | 502 /* |
493 ** Wait for a notify on the condition variable. Sleep for "tiemout" amount | 503 ** 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 | 504 ** of ticks (if "timeout" is zero then the sleep is indefinite). While |
495 ** the thread is waiting it unlocks lock. When the wait has | 505 ** the thread is waiting it unlocks lock. When the wait has |
496 ** finished the thread regains control of the condition variable after | 506 ** finished the thread regains control of the condition variable after |
497 ** locking the associated lock. | 507 ** locking the associated lock. |
498 ** | 508 ** |
499 ** The thread waiting on the condvar will be resumed when the condvar is | 509 ** The thread waiting on the condvar will be resumed when the condvar is |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar))
; | 646 PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar))
; |
637 _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); | 647 _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); |
638 q = q->next; | 648 q = q->next; |
639 } | 649 } |
640 _PR_MD_UNLOCK( &(cvar->ilock) ); | 650 _PR_MD_UNLOCK( &(cvar->ilock) ); |
641 if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); | 651 if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); |
642 | 652 |
643 return PR_SUCCESS; | 653 return PR_SUCCESS; |
644 } /* PRP_NakedBroadcast */ | 654 } /* PRP_NakedBroadcast */ |
645 | 655 |
OLD | NEW |