コード例 #1
0
ファイル: v_networkReader.c プロジェクト: S73417H/opensplice
static v_networkQueue
v_networkReaderSelectBestQueueByReliability(
    v_networkReader reader,
    v_messageQos qos,
    c_bool requiresP2P,
    const char *partitionName,
    const char *topicName)
{
    unsigned int n;
    v_networkQueue currentQueue;
    v_networkQueue bestQueue = NULL;
    v_networkQueue possiblyBestQueue = NULL;
    v_networkQueue bestAlternativeQueue = NULL;
    c_bool reliabilityMatches = FALSE;
    c_bool P2PMatches = FALSE;
    c_bool reliable;
    c_ulong prio,queuePrio;

    assert(reader != NULL);
    assert(C_TYPECHECK(reader, v_networkReader));
    assert(qos != NULL);
    assert(partitionName != NULL);
    assert(topicName != NULL);

    /* Transform kernel prio to networking prio */
    prio = v_messageQos_getTransportPriority(qos);
    reliable = v_messageQos_isReliable(qos);
    /* First select the best queue */
    if (prio < NW_MAX_QUEUE_CACHE_PRIO) {
        if (reliable) {
            bestQueue = reader->queueCache[prio+NW_MAX_QUEUE_CACHE_PRIO];
        } else {
            bestQueue = reader->queueCache[prio];
        }
    }
    if (!bestQueue) {
        for (n=0; (n<reader->nofQueues) && (bestQueue == NULL); n++) {
            currentQueue = reader->queues[n];
            /* Check on reliability */
            if (reliable) {
                reliabilityMatches = v_networkQueueReliable(currentQueue);
            } else {
                reliabilityMatches = !v_networkQueueReliable(currentQueue);
            }
            P2PMatches = (requiresP2P == v_networkQueueP2P(currentQueue));
            if (reliabilityMatches && P2PMatches) {
                queuePrio = v_networkQueuePriority(currentQueue);
                if (prio == queuePrio) {
                    /* An exact match! Stop here */
                    bestQueue = currentQueue;
                } else {
                    if (prio < queuePrio) {
                        /* This queue might be the best fit, it offers higher prio
                         * than requested */
                        if (possiblyBestQueue != NULL) {
                            if (queuePrio < possiblyBestQueue->priority) {
                                possiblyBestQueue = currentQueue;
                            }
                        } else {
                            possiblyBestQueue = currentQueue;
                        }
                    }
                    if (possiblyBestQueue == NULL) {
                        /* No queue fits until now, but this queue
                         * might be the best alternative if no queue
                         * offers the requested prio at all */
                        if (bestAlternativeQueue != NULL) {
                            if (queuePrio > bestAlternativeQueue->priority) {
                                bestAlternativeQueue  = currentQueue;
                            }
                        } else {
                            bestAlternativeQueue = currentQueue;
                        }
                    }
                }
            }
        }
        if (bestQueue == NULL) {
            bestQueue = possiblyBestQueue;
        }
        if (bestQueue == NULL) {
            bestQueue = bestAlternativeQueue;
        }
        if (bestQueue == NULL) {
            OS_REPORT_2(OS_WARNING, "v_networkReaderSelectBestQueue", 0,
                "Unable to select best fitting queue for partition \"%s\", "
                "topic \"%s\". Switching to default", partitionName, topicName);
            bestQueue = reader->defaultQueue;
        }
        if (prio < NW_MAX_QUEUE_CACHE_PRIO) {
            /* Store found bestQueue in the cache, while maintaining
             * correct reference counts on the Queues
             */
            if (reliable) {
                c_free(reader->queueCache[prio+NW_MAX_QUEUE_CACHE_PRIO]);
                reader->queueCache[prio+NW_MAX_QUEUE_CACHE_PRIO] = c_keep(bestQueue);
            } else {
                c_free(reader->queueCache[prio]);
                reader->queueCache[prio] = c_keep(bestQueue);
            }
        }
    }

    return bestQueue;
}
コード例 #2
0
ファイル: v_messageQos.c プロジェクト: osrf/opensplice
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;
}