XnStatus XnLinuxSysVNamedEvent::Wait(XnUInt32 nMilliseconds) { XnStatus nRetVal = XN_STATUS_OK; struct timespec time = {0}; if (nMilliseconds != XN_WAIT_INFINITE) { nRetVal = xnOSGetTimeout(&time, nMilliseconds); if (nRetVal != XN_STATUS_OK) { return XN_STATUS_OS_EVENT_WAIT_FAILED; } } struct sembuf op[2]; // wait for it to be 1 op[0].sem_num = XN_EVENT_SEM_SIGNALED; op[0].sem_op = -1; op[0].sem_flg = 0; // re set it (if manual reset) op[1].sem_num = XN_EVENT_SEM_SIGNALED; op[1].sem_op = 1; op[1].sem_flg = 0; XnInt32 nOpsCount = m_bManualReset ? 2 : 1; if (XN_WAIT_INFINITE != nMilliseconds) { #if _GNU_SOURCE if (0 != semtimedop(m_hSem, op, nOpsCount, &time)) #else if (0 != semop(m_hSem, op, nOpsCount)) #endif { if(EAGAIN == errno) { return XN_STATUS_OS_EVENT_TIMEOUT; } return XN_STATUS_OS_EVENT_WAIT_FAILED; } } else { if (0 != semop(m_hSem, op, nOpsCount)) { return XN_STATUS_OS_EVENT_WAIT_FAILED; } } return (XN_STATUS_OK); }
XN_C_API XnStatus xnOSLockMutex(const XN_MUTEX_HANDLE MutexHandle, XnUInt32 nMilliseconds) { // Local function variables XnStatus nRetVal = XN_STATUS_OK; int rc = 0; // Make sure the actual mutex handle isn't NULL XN_RET_IF_NULL(MutexHandle, XN_STATUS_OS_INVALID_MUTEX); #ifndef XN_PLATFORM_LINUX_NO_SYSV struct sembuf op; // try to decrease it by 1 (if it's 0, we'll wait) op.sem_num = 0; op.sem_op = -1; op.sem_flg = SEM_UNDO; #endif if (nMilliseconds == XN_WAIT_INFINITE) { // lock via the OS if (MutexHandle->bIsNamed) { #ifndef XN_PLATFORM_LINUX_NO_SYSV if (0 != semop(MutexHandle->NamedSem, &op, 1)) { rc = errno; } #endif } else { rc = pthread_mutex_lock(&MutexHandle->ThreadMutex); } } else { struct timespec time; // lock via the OS if (MutexHandle->bIsNamed) { #ifndef XN_PLATFORM_LINUX_NO_SYSV nRetVal = xnOSGetTimeout(&time, nMilliseconds); if (nRetVal != XN_STATUS_OK) { return XN_STATUS_OS_MUTEX_LOCK_FAILED; } #ifndef XN_PLATFORM_HAS_NO_TIMED_OPS if (0 != semtimedop(MutexHandle->NamedSem, &op, 1, &time)) #else if (0 != semop(MutexHandle->NamedSem, &op, 1)) #endif { rc = errno; } #endif } else { // calculate timeout absolute time. First we take current time nRetVal = xnOSGetAbsTimeout(&time, nMilliseconds); if (nRetVal != XN_STATUS_OK) { return XN_STATUS_OS_MUTEX_LOCK_FAILED; } #ifndef XN_PLATFORM_HAS_NO_TIMED_OPS rc = pthread_mutex_timedlock(&MutexHandle->ThreadMutex, &time); #else rc = pthread_mutex_lock(&MutexHandle->ThreadMutex); #endif } } // check for failures if (rc == ETIMEDOUT) { return (XN_STATUS_OS_MUTEX_TIMEOUT); } else if (rc != 0) { return (XN_STATUS_OS_MUTEX_LOCK_FAILED); } // All is good... return (XN_STATUS_OK); }