00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "TSemaphore.h"
00022
00023 ClassImp(TSemaphore)
00024
00025
00026 TSemaphore::TSemaphore(UInt_t initial) : fCond(&fMutex)
00027 {
00028
00029
00030 fValue = initial;
00031 }
00032
00033
00034 Int_t TSemaphore::Wait(Int_t millisec)
00035 {
00036
00037
00038
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
00081
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
00104
00105
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 }