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; }
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; }