/** \brief Suspend the execution of the calling thread for the specified time * * \b os_nanoSleep suspends the calling thread for the required * time by calling \b nanosleep. First it converts the \b delay in * \b os_duration definition into a time in \b struct \b timeval definition. * In case the \b nanosleep is interrupted, the call is re-enterred with * the remaining time. */ os_result ospl_os_sleep ( os_duration delay) { os_result result = os_resultSuccess; DWORD dt; if (OS_DURATION_ISPOSITIVE(delay)) { dt = (DWORD)(delay/1000000); Sleep(dt); } else { result = os_resultFail; } return result; }
/** \brief Suspend the execution of the calling thread for the specified time * * \b os_nanoSleep suspends the calling thread for the required * time by calling \b nanosleep. First it converts the \b delay in * \b os_duration definition into a time in \b struct \b timeval definition. * In case the \b nanosleep is interrupted, the call is re-enterred with * the remaining time. */ os_result ospl_os_sleep ( os_duration delay) { os_result result = os_resultSuccess; DWORD dt; if (OS_DURATION_ISPOSITIVE(delay)) { dt = (DWORD)(delay/1000000); Sleep(dt); } else { /* Negative time-interval should return illegal param error */ result = os_resultFail; } return result; }
DDS::ReturnCode_t DDS::OpenSplice::Utils::copyDurationOut ( const os_duration &from, DDS::Duration_t &to) { DDS::ReturnCode_t result = DDS::RETCODE_OK; assert(!OS_DURATION_ISINVALID(from)); if (OS_DURATION_ISINFINITE(from)) { to.sec = DDS::DURATION_INFINITE_SEC; to.nanosec = DDS::DURATION_INFINITE_NSEC; } else { assert(OS_DURATION_ISPOSITIVE(from)); to.sec = OS_DURATION_GET_SECONDS(from); to.nanosec = OS_DURATION_GET_NANOSECONDS(from); } return result; }
/** \brief Wait for the condition but return when the specified * time has expired before the condition is triggered * * \b os_condTimedWait calls \b pthread_cond_timedwait to * wait for the condition with a timeout. * * \b os_condTimedWait provides an relative time to wait while * \b pthread_cond_timedwait expects an absolute time to wakeup. * The absolute time is calculated from the current time + the * provided relative time. * * \b os_condTimedWait will repeat \b pthread_cond_timedwait in case of an * interrupted system call. Because the time which is passed onto * \b pthread_cond_timedwait is absolute, no remaining time must be * calculated. */ os_result os_condTimedWait ( os_cond *cond, os_mutex *mutex, os_duration timeout) { DWORD wait_time; assert (cond != NULL); assert (mutex != NULL); assert (OS_DURATION_ISPOSITIVE(timeout)); if (timeout < 0) { wait_time = 0; } else { wait_time = (DWORD)(timeout/1000000); } return condTimedWait(cond, mutex, wait_time); }
u_result u_waitsetWaitAction ( const u_waitset _this, u_waitsetAction action, void *arg, const os_duration timeout) { u_result result = U_RESULT_OK; os_result osr; c_ulong length; assert(_this != NULL); assert(action != NULL); assert(OS_DURATION_ISPOSITIVE(timeout)); osr = os_mutexLock_s(&_this->mutex); if (osr == os_resultSuccess) { if (!_this->alive) { result = U_RESULT_ALREADY_DELETED; } if (result == U_RESULT_OK) { if (!_this->waitBusy) { /* Wait for possible detach to complete. * If you don't do that, it's possible that this wait call sets * the waitBusy flag before the detach can wake up of its waitBusy * loop, meaning that the detach will block at least until the * waitset is triggered again. */ while (_this->detachCnt > 0) { os_condWait(&_this->waitCv, &_this->mutex); } _this->waitBusy = TRUE; length = c_iterLength(_this->entries); if (length == 1) { /* Single Domain Mode. */ u_waitsetEntry entry = c_iterObject(_this->entries,0); os_mutexUnlock(&_this->mutex); result = u_waitsetEntryWait(entry, action, arg, timeout); os_mutexLock(&_this->mutex); _this->waitBusy = FALSE; os_condBroadcast(&_this->waitCv); os_mutexUnlock(&_this->mutex); if ((result == U_RESULT_OK) && (_this->alive == FALSE)) { result = U_RESULT_ALREADY_DELETED; } } else { /* Multi Domain Mode (or no Domain). */ if (OS_DURATION_ISINFINITE(timeout)) { os_condWait(&_this->cv, &_this->mutex); osr = os_resultSuccess; } else { osr = os_condTimedWait(&_this->cv, &_this->mutex, timeout); } _this->waitBusy = FALSE; os_condBroadcast(&_this->waitCv); switch (osr) { case os_resultSuccess: if (_this->alive == TRUE) { result = U_RESULT_OK; } else { result = U_RESULT_ALREADY_DELETED; } break; case os_resultTimeout: result = U_RESULT_TIMEOUT; break; default: result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, "u_waitsetWaitAction", result, "os_condWait failed for waitset 0x" PA_ADDRFMT, (PA_ADDRCAST)_this); break; } os_mutexUnlock(&_this->mutex); } } else { os_mutexUnlock(&_this->mutex); result = U_RESULT_PRECONDITION_NOT_MET; } } else { os_mutexUnlock(&_this->mutex); } } else { result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, "u_waitsetWaitAction", result, "os_mutexLock failed for waitset 0x" PA_ADDRFMT, (PA_ADDRCAST)_this); } return result; }
u_result u_waitsetWaitAction2 ( const u_waitset _this, u_waitsetAction2 action, void *arg, const os_duration timeout) { u_result result = U_RESULT_OK; os_result osr; c_ulong length; struct checkArg a; a.action = action; a.arg = arg; a.count = 0; assert(_this != NULL); assert(OS_DURATION_ISPOSITIVE(timeout)); osr = os_mutexLock_s(&_this->mutex); if (osr == os_resultSuccess) { if (!_this->alive) { result = U_RESULT_ALREADY_DELETED; OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result, "Precondition not met: Waitset is already deleted"); } if (_this->waitBusy) { result = U_RESULT_PRECONDITION_NOT_MET; OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result, "Precondition not met: A Wait call is already active on this Waitset"); } if (result == U_RESULT_OK) { /* Wait for possible detach to complete. * If you don't do that, it's possible that this wait call sets * the waitBusy flag before the detach can wake up of its waitBusy * loop, meaning that the detach will block at least until the * waitset is triggered again. */ while (_this->detachCnt > 0) { os_condWait(&_this->waitCv, &_this->mutex); } length = c_iterLength(_this->entries); if (length == 1) { /* Single Domain Mode. */ u_waitsetEntry entry = c_iterObject(_this->entries,0); _this->waitBusy = TRUE; os_mutexUnlock(&_this->mutex); result = u_waitsetEntryWait2(entry, action, arg, timeout); os_mutexLock(&_this->mutex); _this->waitBusy = FALSE; if (_this->notifyDetached) { result = U_RESULT_DETACHING; _this->notifyDetached = OS_FALSE; } os_condBroadcast(&_this->waitCv); os_mutexUnlock(&_this->mutex); if ((result == U_RESULT_OK) && (_this->alive == FALSE)) { result = U_RESULT_ALREADY_DELETED; OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result, "Precondition not met: Waitset is already deleted"); } } else { /* Multi Domain Mode (or no Domain). */ a.count = 0; /* For each Domain test Conditions. */ (void)c_iterWalkUntil(_this->entries, check_entry_conditions, &a); /* Test Guard Conditions */ if ((a.count == 0) && (!action(NULL,arg))) { a.count++; } /* If No Conditions are true then wait. */ if (a.count == 0) { _this->waitBusy = TRUE; if (OS_DURATION_ISINFINITE(timeout)) { os_condWait(&_this->cv, &_this->mutex); osr = os_resultSuccess; } else { osr = os_condTimedWait(&_this->cv, &_this->mutex, timeout); } _this->waitBusy = FALSE; os_condBroadcast(&_this->waitCv); switch (osr) { case os_resultSuccess: if (_this->alive == TRUE) { if (_this->notifyDetached) { result = U_RESULT_DETACHING; _this->notifyDetached = OS_FALSE; } else { result = U_RESULT_OK; } } else { result = U_RESULT_ALREADY_DELETED; OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result, "Precondition not met: Waitset is already deleted"); } break; case os_resultTimeout: result = U_RESULT_TIMEOUT; break; default: result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result, "os_condWait failed for waitset 0x" PA_ADDRFMT, (PA_ADDRCAST)_this); break; } } os_mutexUnlock(&_this->mutex); } } else { os_mutexUnlock(&_this->mutex); } } else { result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result, "os_mutexLock failed for waitset 0x" PA_ADDRFMT, (PA_ADDRCAST)_this); } return result; }