// @(#)root/thread:$Id$
// 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(Int_t millisec)
{
   // If semaphore value is > 0 then decrement it and carry on. If it's
   // already 0 then block. If millisec > 0, apply a relative timeout
   // of millisec milliseconds. Returns 0 in case of success, or mutex errno.

   Int_t rc = 0;

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

   while (fValue == 0) {

      int crc = (millisec > 0) ? fCond.TimedWaitRelative(millisec)
                               : fCond.Wait();

      if (crc != 0) {
         if (crc == 1 && gDebug > 0) {
            Info("Wait", "TCondition::Wait() returns %d [%ld]",
                  crc, TThread::SelfId());
         } else if (crc != 1) {
            Error("Wait", "TCondition::Wait() returns %d [%ld]",
                  crc, TThread::SelfId());
         }
         if ((rc = fMutex.UnLock()))
            Error("Wait", "UnLock on error returns %d [%ld]",
                  rc, TThread::SelfId());
         return crc;
      }
   }

   fValue--;

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

   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 or mutex errno.

   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 and
   // increment the value of the semaphore. Returns 0 in case of success, or
   // mutex errno.

   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;
}
 TSemaphore.cxx:1
 TSemaphore.cxx:2
 TSemaphore.cxx:3
 TSemaphore.cxx:4
 TSemaphore.cxx:5
 TSemaphore.cxx:6
 TSemaphore.cxx:7
 TSemaphore.cxx:8
 TSemaphore.cxx:9
 TSemaphore.cxx:10
 TSemaphore.cxx:11
 TSemaphore.cxx:12
 TSemaphore.cxx:13
 TSemaphore.cxx:14
 TSemaphore.cxx:15
 TSemaphore.cxx:16
 TSemaphore.cxx:17
 TSemaphore.cxx:18
 TSemaphore.cxx:19
 TSemaphore.cxx:20
 TSemaphore.cxx:21
 TSemaphore.cxx:22
 TSemaphore.cxx:23
 TSemaphore.cxx:24
 TSemaphore.cxx:25
 TSemaphore.cxx:26
 TSemaphore.cxx:27
 TSemaphore.cxx:28
 TSemaphore.cxx:29
 TSemaphore.cxx:30
 TSemaphore.cxx:31
 TSemaphore.cxx:32
 TSemaphore.cxx:33
 TSemaphore.cxx:34
 TSemaphore.cxx:35
 TSemaphore.cxx:36
 TSemaphore.cxx:37
 TSemaphore.cxx:38
 TSemaphore.cxx:39
 TSemaphore.cxx:40
 TSemaphore.cxx:41
 TSemaphore.cxx:42
 TSemaphore.cxx:43
 TSemaphore.cxx:44
 TSemaphore.cxx:45
 TSemaphore.cxx:46
 TSemaphore.cxx:47
 TSemaphore.cxx:48
 TSemaphore.cxx:49
 TSemaphore.cxx:50
 TSemaphore.cxx:51
 TSemaphore.cxx:52
 TSemaphore.cxx:53
 TSemaphore.cxx:54
 TSemaphore.cxx:55
 TSemaphore.cxx:56
 TSemaphore.cxx:57
 TSemaphore.cxx:58
 TSemaphore.cxx:59
 TSemaphore.cxx:60
 TSemaphore.cxx:61
 TSemaphore.cxx:62
 TSemaphore.cxx:63
 TSemaphore.cxx:64
 TSemaphore.cxx:65
 TSemaphore.cxx:66
 TSemaphore.cxx:67
 TSemaphore.cxx:68
 TSemaphore.cxx:69
 TSemaphore.cxx:70
 TSemaphore.cxx:71
 TSemaphore.cxx:72
 TSemaphore.cxx:73
 TSemaphore.cxx:74
 TSemaphore.cxx:75
 TSemaphore.cxx:76
 TSemaphore.cxx:77
 TSemaphore.cxx:78
 TSemaphore.cxx:79
 TSemaphore.cxx:80
 TSemaphore.cxx:81
 TSemaphore.cxx:82
 TSemaphore.cxx:83
 TSemaphore.cxx:84
 TSemaphore.cxx:85
 TSemaphore.cxx:86
 TSemaphore.cxx:87
 TSemaphore.cxx:88
 TSemaphore.cxx:89
 TSemaphore.cxx:90
 TSemaphore.cxx:91
 TSemaphore.cxx:92
 TSemaphore.cxx:93
 TSemaphore.cxx:94
 TSemaphore.cxx:95
 TSemaphore.cxx:96
 TSemaphore.cxx:97
 TSemaphore.cxx:98
 TSemaphore.cxx:99
 TSemaphore.cxx:100
 TSemaphore.cxx:101
 TSemaphore.cxx:102
 TSemaphore.cxx:103
 TSemaphore.cxx:104
 TSemaphore.cxx:105
 TSemaphore.cxx:106
 TSemaphore.cxx:107
 TSemaphore.cxx:108
 TSemaphore.cxx:109
 TSemaphore.cxx:110
 TSemaphore.cxx:111
 TSemaphore.cxx:112
 TSemaphore.cxx:113
 TSemaphore.cxx:114
 TSemaphore.cxx:115
 TSemaphore.cxx:116
 TSemaphore.cxx:117
 TSemaphore.cxx:118
 TSemaphore.cxx:119