// @(#)root/thread:$Name:  $:$Id: TSemaphore.cxx,v 1.2 2004/12/10 12:13:33 rdm Exp $
// Author: Fons Rademakers   02/07/97

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSemaphore                                                           //
//                                                                      //
// This class implements a counting semaphore. Use a semaphore          //
// to synchronize threads.                                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TSemaphore.h"

ClassImp(TSemaphore)

//______________________________________________________________________________
 TSemaphore::TSemaphore(UInt_t initial) : fCond(&fMutex)
{
   // Create counting semaphore.

   fValue = initial;
}

//______________________________________________________________________________
 Int_t TSemaphore::Wait()
{
   // If semaphore value is > 0 then decrement it and carry on. If it's
   // already 0 then block.

   int r = fMutex.Lock();
   if (r) { Error("Wait","Lock returns %d [%ld]", r, TThread::SelfId()); return r; }

   while (fValue == 0) {
      int rc = fCond.Wait();

      if (rc != 0) {
         Error("Wait","TCondition::Wait() returns %d [%ld]", rc, TThread::SelfId());
         r = fMutex.UnLock();
         if (r) Error("Wait","UnLock on error returns %d [%ld]", r, TThread::SelfId());
         return rc;
      }
   }

   fValue--;

   r = fMutex.UnLock();
   if (r) { Error("Wait","UnLock returns %d [%ld]", r, TThread::SelfId()); return r; }

   return 0;
}

//______________________________________________________________________________
 Int_t TSemaphore::TryWait()
{
   // If semaphore value is > 0 then decrement it and return 0. If it's
   // already 0 then return 1.

   int r = fMutex.Lock();
   if (r) { Error("TryWait","Lock returns %d [%ld]", r, TThread::SelfId()); return r; }

   if (fValue == 0) {
      r = fMutex.UnLock();
      if (r) Error("TryWait","UnLock on fail returns %d [%ld]", r, TThread::SelfId());
      return 1;
   }

   fValue--;

   r = fMutex.UnLock();
   if (r) { Error("TryWait","UnLock returns %d [%ld]", r, TThread::SelfId()); return r; }

   return 0;
}

//______________________________________________________________________________
 Int_t TSemaphore::Post()
{
   // If any threads are blocked in Wait(), wake one of them up. Otherwise
   // increment the value of the semaphore.

   int r = fMutex.Lock();
   if (r) { Error("Post","Lock returns %d [%ld]", r, TThread::SelfId()); return r; }

   Bool_t doSignal = fValue == 0;
   fValue++;

   r = fMutex.UnLock();
   if (r) { Error("Post","UnLock returns %d [%ld]", r, TThread::SelfId()); return r; }

   if (doSignal) fCond.Signal();

   return 0;
}


ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.