#ifndef WIN32 #include #include #endif #include "GLTB/exception.h" #include "GLTB/semaphore.h" namespace gltb { Semaphore::Semaphore(int maxCount, int initialCount) { #ifdef WIN32 semaphoreHandle=CreateSemaphore(NULL,initialCount,maxCount,NULL); if(semaphoreHandle==NULL) { int error=GetLastError(); throw Exception("CreateSemaphore failed","Semaphore::Semaphore()"); } #else if(sem_init(&semaphore, 0, initialCount) != 0) { throw Exception("sem_init() failed", "Semaphore::Semaphore()"); } #endif } Semaphore::~Semaphore() { #ifdef WIN32 CloseHandle(semaphoreHandle); #else sem_destroy(&semaphore); #endif } void Semaphore::signal() { #ifdef WIN32 ReleaseSemaphore(semaphoreHandle, 1, NULL); #else if(sem_post(&semaphore) != 0) { throw Exception("sem_post() failed", "Semaphore::signal()"); } #endif } void Semaphore::wait() { #ifdef WIN32 int result=WaitForSingleObject(semaphoreHandle, INFINITE); if(result==WAIT_FAILED) { int error=GetLastError(); throw Exception("WaitForSingleObject failed","Semaphore::wait()"); } #else if(sem_wait(&semaphore) != 0) { throw Exception("sem_wait() failed", "Semaphore::wait()"); } #endif } bool Semaphore::wait(int timeout) { #ifdef WIN32 int result=WaitForSingleObject(semaphoreHandle,timeout); switch(result) { case WAIT_OBJECT_0: return true; case WAIT_ABANDONED: return true; case WAIT_TIMEOUT: return false; case WAIT_FAILED: int error=GetLastError(); throw Exception("WaitForSingleObject failed","Semaphore::wait()"); } return false; #else timespec time; clock_gettime(CLOCK_REALTIME,&time); time.tv_nsec+=timeout*1000000; while(time.tv_nsec>1000000000) { // correct nanoseconds overflow time.tv_sec++; time.tv_nsec-=1000000000; } int result; while((result = sem_timedwait(&semaphore, &time)) != 0) { if(errno == ETIMEDOUT) { return false; } else { throw Exception("sem_timedwait() failed", "Semaphore::wait()"); } } return true; #endif } RefPtr Semaphore::createSemaphore(int maxCount, int initialCount) { return new Semaphore(maxCount,initialCount); } }