Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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;
}