/*******************************************************************************
* BSema.cc BSema Classes
* T.Barnaby, BEAM Ltd, 6/11/02
* updated by D.Korchagin, CERN AB-BI-SW, 2007-08-31
*******************************************************************************
*/
#include <BSema.h>
#include <errno.h>
#include <sys/time.h>
BSema::BSema(int value){
sem_init(&osema, 0, value);
}
BSema::BSema(const BSema& sema){
sem_init(&osema, 0, sema.getValue());
}
BSema& BSema::operator=(const BSema& sema){
sem_destroy(&osema);
sem_init(&osema, 0, sema.getValue());
return *this;
}
BSema::~BSema(){
sem_destroy(&osema);
}
int BSema::post(){
return sem_post(&osema);
}
int BSema::wait(){
int r;
while(1){
r = sem_wait(&osema);
if(r >= 0)
break;
else if((r < 0) && (errno != EINTR))
break;
}
return r;
}
int BSema::timedWait(int timeOutUs){
struct timeval tv;
struct timespec ts;
gettimeofday(&tv, 0);
ts.tv_sec = tv.tv_sec + timeOutUs / 1000000;
ts.tv_nsec = (tv.tv_usec + timeOutUs % 1000000) * 1000;
ts.tv_sec += (ts.tv_nsec / 1000000000);
ts.tv_nsec %= 1000000000;
#ifndef __Lynx__
return sem_timedwait(&osema, &ts);
#else
#ifdef HAVE_SEM_TIMEDWAIT
// LynxOS 4.2 new features - support has been added for two routines from POSIX 1003.1-2001, sem_timedwait() and pthread_mutex_timedlock(), etc.
return sem_timedwait(&osema, &ts);
#else
// sem_timedwait() is not available for LynxOS 4.0 or previous versions - use sem_wait() instead.
return sem_wait(&osema);
#endif
#endif
}
int BSema::tryWait(){
return sem_trywait(&osema);
}
int BSema::getValue() const {
int v;
sem_getvalue((sem_t*)&osema, &v);
return v;
}