#include "TSemaphore.h"
ClassImp(TSemaphore)
TSemaphore::TSemaphore(UInt_t initial) : fCond(&fMutex)
{
fValue = initial;
}
Int_t TSemaphore::Wait(Int_t millisec)
{
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()
{
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()
{
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;
}