| OLD | NEW |
| (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 #include "primpl.h" | |
| 7 #include "obsolete/prsem.h" | |
| 8 | |
| 9 /************************************************************************/ | |
| 10 | |
| 11 /* | |
| 12 ** Create a new semaphore. | |
| 13 */ | |
| 14 PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value) | |
| 15 { | |
| 16 PRSemaphore *sem; | |
| 17 PRCondVar *cvar; | |
| 18 PRLock *lock; | |
| 19 | |
| 20 sem = PR_NEWZAP(PRSemaphore); | |
| 21 if (sem) { | |
| 22 #ifdef HAVE_CVAR_BUILT_ON_SEM | |
| 23 _PR_MD_NEW_SEM(&sem->md, value); | |
| 24 #else | |
| 25 lock = PR_NewLock(); | |
| 26 if (!lock) { | |
| 27 PR_DELETE(sem); | |
| 28 return NULL; | |
| 29 } | |
| 30 | |
| 31 cvar = PR_NewCondVar(lock); | |
| 32 if (!cvar) { | |
| 33 PR_DestroyLock(lock); | |
| 34 PR_DELETE(sem); | |
| 35 return NULL; | |
| 36 } | |
| 37 sem->cvar = cvar; | |
| 38 sem->count = value; | |
| 39 #endif | |
| 40 } | |
| 41 return sem; | |
| 42 } | |
| 43 | |
| 44 /* | |
| 45 ** Destroy a semaphore. There must be no thread waiting on the semaphore. | |
| 46 ** The caller is responsible for guaranteeing that the semaphore is | |
| 47 ** no longer in use. | |
| 48 */ | |
| 49 PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *sem) | |
| 50 { | |
| 51 #ifdef HAVE_CVAR_BUILT_ON_SEM | |
| 52 _PR_MD_DESTROY_SEM(&sem->md); | |
| 53 #else | |
| 54 PR_ASSERT(sem->waiters == 0); | |
| 55 | |
| 56 PR_DestroyLock(sem->cvar->lock); | |
| 57 PR_DestroyCondVar(sem->cvar); | |
| 58 #endif | |
| 59 PR_DELETE(sem); | |
| 60 } | |
| 61 | |
| 62 /* | |
| 63 ** Wait on a Semaphore. | |
| 64 ** | |
| 65 ** This routine allows a calling thread to wait or proceed depending upon the | |
| 66 ** state of the semahore sem. The thread can proceed only if the counter value | |
| 67 ** of the semaphore sem is currently greater than 0. If the value of semaphore | |
| 68 ** sem is positive, it is decremented by one and the routine returns immediately
| |
| 69 ** allowing the calling thread to continue. If the value of semaphore sem is 0, | |
| 70 ** the calling thread blocks awaiting the semaphore to be released by another | |
| 71 ** thread. | |
| 72 ** | |
| 73 ** This routine can return PR_PENDING_INTERRUPT if the waiting thread | |
| 74 ** has been interrupted. | |
| 75 */ | |
| 76 PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *sem) | |
| 77 { | |
| 78 PRStatus status = PR_SUCCESS; | |
| 79 | |
| 80 #ifdef HAVE_CVAR_BUILT_ON_SEM | |
| 81 return _PR_MD_WAIT_SEM(&sem->md); | |
| 82 #else | |
| 83 PR_Lock(sem->cvar->lock); | |
| 84 while (sem->count == 0) { | |
| 85 sem->waiters++; | |
| 86 status = PR_WaitCondVar(sem->cvar, PR_INTERVAL_NO_TIMEOUT); | |
| 87 sem->waiters--; | |
| 88 if (status != PR_SUCCESS) | |
| 89 break; | |
| 90 } | |
| 91 if (status == PR_SUCCESS) | |
| 92 sem->count--; | |
| 93 PR_Unlock(sem->cvar->lock); | |
| 94 #endif | |
| 95 | |
| 96 return (status); | |
| 97 } | |
| 98 | |
| 99 /* | |
| 100 ** This routine increments the counter value of the semaphore. If other threads | |
| 101 ** are blocked for the semaphore, then the scheduler will determine which ONE | |
| 102 ** thread will be unblocked. | |
| 103 */ | |
| 104 PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *sem) | |
| 105 { | |
| 106 #ifdef HAVE_CVAR_BUILT_ON_SEM | |
| 107 _PR_MD_POST_SEM(&sem->md); | |
| 108 #else | |
| 109 PR_Lock(sem->cvar->lock); | |
| 110 if (sem->waiters) | |
| 111 PR_NotifyCondVar(sem->cvar); | |
| 112 sem->count++; | |
| 113 PR_Unlock(sem->cvar->lock); | |
| 114 #endif | |
| 115 } | |
| 116 | |
| 117 #if DEBUG | |
| 118 /* | |
| 119 ** Returns the value of the semaphore referenced by sem without affecting | |
| 120 ** the state of the semaphore. The value represents the semaphore vaule | |
| 121 ** at the time of the call, but may not be the actual value when the | |
| 122 ** caller inspects it. (FOR DEBUGGING ONLY) | |
| 123 */ | |
| 124 PR_IMPLEMENT(PRUintn) PR_GetValueSem(PRSemaphore *sem) | |
| 125 { | |
| 126 PRUintn rv; | |
| 127 | |
| 128 #ifdef HAVE_CVAR_BUILT_ON_SEM | |
| 129 rv = _PR_MD_GET_VALUE_SEM(&sem->md); | |
| 130 #else | |
| 131 PR_Lock(sem->cvar->lock); | |
| 132 rv = sem->count; | |
| 133 PR_Unlock(sem->cvar->lock); | |
| 134 #endif | |
| 135 | |
| 136 return rv; | |
| 137 } | |
| 138 #endif | |
| OLD | NEW |