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; }
v_dataReaderSample v_dataReaderSampleNew( v_dataReaderInstance instance, v_message message) { v_dataReader dataReader; v_dataReaderSample sample; v_readerQos readerQos; v_index index; os_timeE msgEpoch; assert(instance != NULL); assert(C_TYPECHECK(message,v_message)); index = v_index(instance->index); dataReader = v_dataReader(index->reader); readerQos = v_reader(dataReader)->qos; assert(readerQos); sample = v_dataReaderSample(c_new(dataReader->sampleType)); if (sample != NULL) { v_readerSample(sample)->instance = (c_voidp)instance; v_readerSample(sample)->viewSamples = NULL; v_readerSample(sample)->sampleState = 0; sample->insertTime = os_timeWGet(); /* The expiry time calculation is dependent on the DestinationOrderQos(readerQos->orderby.v.kind): * In case of the by_reception_timestamp kind the expiry time is determined based on insertion time(sample->insertTime). * In case of the by_source_timestamp kind the expiry time is determined based on source time (message->writeTime). */ msgEpoch = os_timeEGet(); if (readerQos->orderby.v.kind == V_ORDERBY_SOURCETIME) { /* assuming wall clocks of source and destination are aligned! * calculate the age of the message and then correct the message epoch. */ os_duration message_age = os_timeWDiff(os_timeWGet(), message->writeTime); msgEpoch = os_timeESub(msgEpoch, message_age); } v_dataReaderSampleTemplate(sample)->message = c_keep(message); sample->disposeCount = instance->disposeCount; sample->noWritersCount = instance->noWritersCount; sample->publicationHandle = message->writerGID; sample->readId = 0; sample->newer = NULL; /* When both ReaderLifespanQos(readerQos->lifespan.used) and the inline LifespanQos (v_messageQos_getLifespanPeriod(message->qos)) * are set the expiryTime will be set to the earliest time among them. */ if (message->qos) { os_duration lifespan = v_messageQos_getLifespanPeriod(message->qos); if (readerQos->lifespan.v.used) { if (os_durationCompare(readerQos->lifespan.v.duration, lifespan) == OS_LESS) { v_lifespanSample(sample)->expiryTime = os_timeEAdd(msgEpoch, readerQos->lifespan.v.duration); } else { v_lifespanSample(sample)->expiryTime = os_timeEAdd(msgEpoch, lifespan); } v_lifespanAdminInsert(v_dataReaderEntry(index->entry)->lifespanAdmin, v_lifespanSample(sample)); } else { if (OS_DURATION_ISINFINITE(lifespan)) { v_lifespanSample(sample)->expiryTime = OS_TIMEE_INFINITE; } else { v_lifespanSample(sample)->expiryTime = os_timeEAdd(msgEpoch, lifespan); v_lifespanAdminInsert(v_dataReaderEntry(index->entry)->lifespanAdmin, v_lifespanSample(sample)); } } } else { if (readerQos->lifespan.v.used) { v_lifespanSample(sample)->expiryTime = os_timeEAdd(msgEpoch,readerQos->lifespan.v.duration); v_lifespanAdminInsert(v_dataReaderEntry(index->entry)->lifespanAdmin, v_lifespanSample(sample)); } else { v_lifespanSample(sample)->expiryTime = OS_TIMEE_INFINITE; } } } else { OS_REPORT(OS_FATAL, OS_FUNCTION, V_RESULT_INTERNAL_ERROR, "Failed to allocate v_dataReaderSample."); } return sample; }
v_messageQos v_messageQos_from_wqos_new( v_writerQos wqos, c_type msgQosType, v_presentationKind access_scope, c_bool coherent_access, c_bool ordered_access) { v_messageQos _this; c_base base; v_duration tdur; c_ulong offset = 6, /* byte0 + byte1 + transport_priority */ strength_offset = 0, latency_offset = 0, deadline_offset = 0, liveliness_offset = 0, lifespan_offset = 0; c_octet byte0, byte1; c_octet *dst, *src; assert(C_TYPECHECK(wqos,v_writerQos)); base = c_getBase(wqos); if (msgQosType == NULL) { msgQosType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY<c_octet>", c_octet_t(base), 0); } byte0 = (c_octet) (_LSHIFT_(wqos->reliability.v.kind, MQ_BYTE0_RELIABILITY_OFFSET) | _LSHIFT_(wqos->ownership.v.kind, MQ_BYTE0_OWNERSHIP_OFFSET) | _LSHIFT_(wqos->orderby.v.kind, MQ_BYTE0_ORDERBY_OFFSET) | _LSHIFT_(wqos->lifecycle.v.autodispose_unregistered_instances, MQ_BYTE0_AUTODISPOSE_OFFSET)); byte1 = (c_octet) (_LSHIFT_(wqos->durability.v.kind, MQ_BYTE1_DURABILITY_OFFSET) | _LSHIFT_(wqos->liveliness.v.kind, MQ_BYTE1_LIVELINESS_OFFSET) | /* writer->resend._d contains the access_scope of the publisher-QoS */ _LSHIFT_(access_scope, MQ_BYTE1_PRESENTATION_OFFSET) | _LSHIFT_(coherent_access, MQ_BYTE1_COHERENT_ACCESS_OFFSET) | _LSHIFT_(ordered_access, MQ_BYTE1_ORDERED_ACCESS_OFFSET)); if (wqos->ownership.v.kind == V_OWNERSHIP_EXCLUSIVE) { strength_offset = offset; offset += (c_ulong) sizeof(wqos->strength.v.value); } if (OS_DURATION_ISZERO(wqos->latency.v.duration)) { byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_LATENCY_OFFSET)); } else { latency_offset = offset; offset += (c_ulong) sizeof(wqos->latency.v.duration); } if (OS_DURATION_ISINFINITE(wqos->deadline.v.period)) { byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_DEADLINE_OFFSET)); } else { deadline_offset = offset; offset += (c_ulong) sizeof(wqos->deadline.v.period); } if (OS_DURATION_ISINFINITE(wqos->liveliness.v.lease_duration)) { byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_LIVELINESS_OFFSET)); } else { liveliness_offset = offset; offset += (c_ulong) sizeof(wqos->liveliness.v.lease_duration); } if (OS_DURATION_ISINFINITE(wqos->lifespan.v.duration)) { byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_LIFESPAN_OFFSET)); } else { lifespan_offset = offset; offset += (c_ulong) sizeof(wqos->lifespan.v.duration); } _this = c_newArray((c_collectionType)msgQosType,offset); if (_this) { ((c_octet *)_this)[0] = byte0; ((c_octet *)_this)[1] = byte1; src = (c_octet *)&wqos->transport.v.value; dst = (c_octet *)&((c_octet *)_this)[2]; _COPY4_(dst,src); if (strength_offset) { src = (c_octet *)&wqos->strength.v.value; dst = (c_octet *)&((c_octet *)_this)[strength_offset]; _COPY4_(dst,src); } if (latency_offset) { tdur = v_durationFromOsDuration(wqos->latency.v.duration); src = (c_octet *)&tdur; dst = (c_octet *)&((c_octet *)_this)[latency_offset]; _COPY8_(dst,src); } if (deadline_offset) { tdur = v_durationFromOsDuration(wqos->deadline.v.period); src = (c_octet *)&tdur; dst = (c_octet *)&((c_octet *)_this)[deadline_offset]; _COPY8_(dst,src); } if (liveliness_offset) { tdur = v_durationFromOsDuration(wqos->liveliness.v.lease_duration); src = (c_octet *)&tdur; dst = (c_octet *)&((c_octet *)_this)[liveliness_offset]; _COPY8_(dst,src); } if (lifespan_offset) { tdur = v_durationFromOsDuration(wqos->lifespan.v.duration); src = (c_octet *)&tdur; dst = (c_octet *)&((c_octet *)_this)[lifespan_offset]; _COPY8_(dst,src); } } else { OS_REPORT(OS_CRITICAL, "v_messageQos_new",V_RESULT_INTERNAL_ERROR, "Failed to allocate messageQos."); assert(FALSE); } return _this; }
c_bool v_messageQos_isReaderCompatible ( v_messageQos _this, v_reader r) { v_duration duration; c_octet *dst, *src; c_long offset; v_readerQos qos; qos = r->qos; if (_this == NULL) { /* Messages without Qos are implied lifecycle changes (for example resulting * from a call to the dispose_all_data operation on the topic) and should * always be delivered to all readers. Readers that have no corresponding * instance will automatically ignore these implied lifecycle changes. */ return TRUE; } if ((qos->reliability.v.kind == V_RELIABILITY_RELIABLE) && !v_messageQos_isReliable(_this)) { return FALSE; } if (qos->durability.v.kind > v_messageQos_durabilityKind(_this)) { return FALSE; } if (qos->ownership.v.kind != v_messageQos_ownershipKind(_this)) { return FALSE; } if (r->subQos->presentation.v.access_scope > v_messageQos_presentationKind(_this)) { return FALSE; } if ((r->subQos->presentation.v.ordered_access == TRUE) && (!v_messageQos_isOrderedAccess(_this))) { return FALSE; } if ((r->subQos->presentation.v.coherent_access == TRUE) && (!v_messageQos_isCoherentAccess(_this))) { return FALSE; } if (qos->liveliness.v.kind > v_messageQos_livelinessKind(_this)) { return FALSE; } if (qos->orderby.v.kind > v_messageQos_orderbyKind(_this)) { return FALSE; } dst = (c_octet *)&duration; offset = 6 + v_messageQos_strengthSize(_this); if (!v_messageQos_isZeroLatency(_this)) { if (!OS_DURATION_ISINFINITE(qos->latency.v.duration)) { src = &(((c_octet *)_this))[offset]; _COPY8_(dst,src); if (os_durationCompare(v_durationToOsDuration(duration), qos->latency.v.duration) == OS_MORE) { return FALSE; } } offset += 8; } if (!OS_DURATION_ISINFINITE(qos->deadline.v.period)) { if (v_messageQos_isInfiniteDeadline(_this)) { return FALSE; } else { src = &(((c_octet *)_this))[offset]; _COPY8_(dst,src); if (os_durationCompare(v_durationToOsDuration(duration), qos->deadline.v.period) == OS_MORE) { return FALSE; } } } offset += v_messageQos_deadlineSize(_this); if (!OS_DURATION_ISINFINITE(qos->liveliness.v.lease_duration)) { if (!v_messageQos_isInfiniteLiveliness(_this)) { src = &(((c_octet *)_this))[offset]; _COPY8_(dst,src); if (os_durationCompare(v_durationToOsDuration(duration), qos->liveliness.v.lease_duration) == OS_MORE) { return FALSE; } } } return TRUE; }
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; }