nsprpub/pr/src/threads/prsem.c

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     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/. */
     6 #include "primpl.h"
     7 #include "obsolete/prsem.h"
     9 /************************************************************************/
    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;
    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     	}
    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 }
    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);
    56     PR_DestroyLock(sem->cvar->lock);
    57     PR_DestroyCondVar(sem->cvar);
    58 #endif
    59     PR_DELETE(sem);
    60 }
    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;
    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
    96 	return (status);
    97 }
    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 }
   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;
   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
   136 	return rv;
   137 }
   138 #endif

mercurial