tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

prsem.c (3468B)


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