// routines to use it (p blocks, cond p does not) // 1 on success, -1 fail int vrpn_Semaphore::p() { #ifdef sgi if (fUsingLock) { if (ussetlock(l) != 1) { perror("vrpn_Semaphore::p: ussetlock:"); return -1; } } else { if (uspsema(ps) != 1) { perror("vrpn_Semaphore::p: uspsema:"); return -1; } } #elif defined(_WIN32) switch (WaitForSingleObject(hSemaphore, INFINITE)) { case WAIT_OBJECT_0: // got the resource break; case WAIT_TIMEOUT: ALL_ASSERT(0, "vrpn_Semaphore::p: infinite wait time timed out!"); return -1; break; case WAIT_ABANDONED: ALL_ASSERT(0, "vrpn_Semaphore::p: thread holding resource died"); return -1; break; case WAIT_FAILED: // get error info from windows (from FormatMessage help page) LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL); fprintf(stderr, "vrpn_Semaphore::p: error waiting for resource, " "WIN32 WaitForSingleObject call caused the following error: %s", (LPTSTR)lpMsgBuf); // Free the buffer. LocalFree(lpMsgBuf); return -1; break; default: ALL_ASSERT(0, "vrpn_Semaphore::p: unknown return code"); return -1; } #else // Posix by default if (sem_wait(semaphore) != 0) { perror("vrpn_Semaphore::p: "); return -1; } #endif return 1; }
void SemaphoreGuard::handleLockResult_(int result) { ALL_ASSERT(result >= 0, "Lock error!"); if (result == 1) { locked_ = true; } }
/// @brief Unlocks the resource, if we have locked it. void SemaphoreGuard::unlock() { if (locked_) { int result = sem_.v(); ALL_ASSERT(result == 0, "failed to unlock semaphore!"); locked_ = false; } }
// 0 if it can't get the resource, 1 if it can // -1 if fail int vrpn_Semaphore::condP() { int iRetVal=1; #ifdef sgi if (fUsingLock) { // don't spin at all iRetVal = uscsetlock(l, 0); if (iRetVal<=0) { perror("vrpn_Semaphore::condP: uscsetlock:"); return -1; } } else { iRetVal = uscpsema(ps); if (iRetVal<=0) { perror("vrpn_Semaphore::condP: uscpsema:"); return -1; } } #elif defined(_WIN32) switch (WaitForSingleObject(hSemaphore, 0)) { case WAIT_OBJECT_0: // got the resource break; case WAIT_TIMEOUT: // resource not free iRetVal=0; break; case WAIT_ABANDONED: ALL_ASSERT(0,"vrpn_Semaphore::condP: thread holding resource died"); return -1; break; case WAIT_FAILED: // get error info from windows (from FormatMessage help page) LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); fprintf(stderr, "Semaphore::condP: error waiting for resource, " "WIN32 WaitForSingleObject call caused the following error: %s", (LPTSTR) lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); return -1; break; default: ALL_ASSERT(0,"vrpn_Semaphore::p: unknown return code"); return -1; } #else // Posix by default iRetVal = sem_trywait(semaphore); if (iRetVal == 0) { iRetVal = 1; } else if (errno == EAGAIN) { iRetVal = 0; } else { perror("vrpn_Semaphore::condP: "); iRetVal = -1; } #endif return iRetVal; }