TSemaphore.cxx

Go to the documentation of this file.
00001 // @(#)root/thread:$Id: TSemaphore.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Fons Rademakers   02/07/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TSemaphore                                                           //
00015 //                                                                      //
00016 // This class implements a counting semaphore. Use a semaphore          //
00017 // to synchronize threads.                                              //
00018 //                                                                      //
00019 //////////////////////////////////////////////////////////////////////////
00020 
00021 #include "TSemaphore.h"
00022 
00023 ClassImp(TSemaphore)
00024 
00025 //______________________________________________________________________________
00026 TSemaphore::TSemaphore(UInt_t initial) : fCond(&fMutex)
00027 {
00028    // Create counting semaphore.
00029 
00030    fValue = initial;
00031 }
00032 
00033 //______________________________________________________________________________
00034 Int_t TSemaphore::Wait(Int_t millisec)
00035 {
00036    // If semaphore value is > 0 then decrement it and carry on. If it's
00037    // already 0 then block. If millisec > 0, apply a relative timeout
00038    // of millisec milliseconds. Returns 0 in case of success, or mutex errno.
00039 
00040    Int_t rc = 0;
00041 
00042    if ((rc = fMutex.Lock())) {
00043       Error("Wait","Lock returns %d [%ld]", rc, TThread::SelfId());
00044       return rc;
00045    }
00046 
00047    while (fValue == 0) {
00048 
00049       int crc = (millisec > 0) ? fCond.TimedWaitRelative(millisec)
00050                                : fCond.Wait();
00051 
00052       if (crc != 0) {
00053          if (crc == 1 && gDebug > 0) {
00054             Info("Wait", "TCondition::Wait() returns %d [%ld]",
00055                   crc, TThread::SelfId());
00056          } else if (crc != 1) {
00057             Error("Wait", "TCondition::Wait() returns %d [%ld]",
00058                   crc, TThread::SelfId());
00059          }
00060          if ((rc = fMutex.UnLock()))
00061             Error("Wait", "UnLock on error returns %d [%ld]",
00062                   rc, TThread::SelfId());
00063          return crc;
00064       }
00065    }
00066 
00067    fValue--;
00068 
00069    if ((rc = fMutex.UnLock())) {
00070       Error("Wait", "UnLock returns %d [%ld]", rc, TThread::SelfId());
00071       return rc;
00072    }
00073 
00074    return 0;
00075 }
00076 
00077 //______________________________________________________________________________
00078 Int_t TSemaphore::TryWait()
00079 {
00080    // If semaphore value is > 0 then decrement it and return 0. If it's
00081    // already 0 then return 1 or mutex errno.
00082 
00083    int r = fMutex.Lock();
00084    if (r) { Error("TryWait","Lock returns %d [%ld]", r, TThread::SelfId()); return r; }
00085 
00086    if (fValue == 0) {
00087       r = fMutex.UnLock();
00088       if (r) Error("TryWait","UnLock on fail returns %d [%ld]", r, TThread::SelfId());
00089       return 1;
00090    }
00091 
00092    fValue--;
00093 
00094    r = fMutex.UnLock();
00095    if (r) { Error("TryWait","UnLock returns %d [%ld]", r, TThread::SelfId()); return r; }
00096 
00097    return 0;
00098 }
00099 
00100 //______________________________________________________________________________
00101 Int_t TSemaphore::Post()
00102 {
00103    // If any threads are blocked in Wait(), wake one of them up and
00104    // increment the value of the semaphore. Returns 0 in case of success, or
00105    // mutex errno.
00106 
00107    int r = fMutex.Lock();
00108    if (r) { Error("Post","Lock returns %d [%ld]", r, TThread::SelfId()); return r; }
00109 
00110    Bool_t doSignal = fValue == 0;
00111    fValue++;
00112 
00113    r = fMutex.UnLock();
00114    if (r) { Error("Post","UnLock returns %d [%ld]", r, TThread::SelfId()); return r; }
00115 
00116    if (doSignal) fCond.Signal();
00117 
00118    return 0;
00119 }

Generated on Tue Jul 5 14:12:02 2011 for ROOT_528-00b_version by  doxygen 1.5.1