os_duration v_messageQos_getLatencyPeriod( v_messageQos qos) { os_duration budget; c_octet *dst; c_octet *src; if (v_messageQos_isZeroLatency(qos)) { budget = OS_DURATION_ZERO; } else { v_duration tmp; dst = (c_octet *)&tmp; src = &(((c_octet *)qos))[6+v_messageQos_strengthSize(qos)]; _COPY8_(dst,src); budget = v_durationToOsDuration(tmp); } return budget; }
c_bool v_networkQueueWrite( v_networkQueue queue, v_message msg, v_networkReaderEntry entry, c_long sequenceNumber, v_gid sender, c_bool sendTo, /* for p2p writing */ v_gid receiver) { c_bool result = TRUE; c_bool wasEmpty; c_bool found; v_networkStatusMarker *currentMarkerPtr; v_networkStatusMarker currentMarker; v_networkStatusMarker marker; v_networkQueueSample newHolder; c_ulonglong msecsTime; c_ulonglong msecsResult; c_ulonglong msecsLeftOver; c_time sendBeforeNoTrunc; c_time sendBefore; c_time now; c_ulong priorityLookingFor; c_equality eq; c_bool newMarkerCreated = FALSE; c_bool sendNow = FALSE; V_MESSAGE_STAMP(msg,readerInsertTime); c_mutexLock(&queue->mutex); /* numberOfSamplesArrived statistics */ v_networkQueueStatisticsAdd(numberOfSamplesArrived,queue->statistics); if (queue->currentMsgCount == queue->maxMsgCount) { c_mutexUnlock(&queue->mutex); /* numberOfSamplesRejected stat */ v_networkQueueStatisticsAdd(numberOfSamplesRejected,queue->statistics); return FALSE; } currentMarkerPtr = &(queue->firstStatusMarker); currentMarker = *currentMarkerPtr; if (queue->threadWaiting) { wasEmpty = !v_networkQueueHasExpiringData(queue); } else { wasEmpty = FALSE; } marker = NULL; found = FALSE; priorityLookingFor = v_messageQos_getTransportPriority(msg->qos); if (queue->periodic) { if (v_messageQos_isZeroLatency(msg->qos)) { sendBefore = C_TIME_ZERO; sendNow = TRUE; } else { #ifdef _NAT_ now = v_timeGet(); #else now = msg->allocTime; #endif sendBeforeNoTrunc = c_timeAdd(now, v_messageQos_getLatencyPeriod(msg->qos)); TIME_TO_MSEC(sendBeforeNoTrunc, msecsTime); msecsLeftOver = (c_ulonglong)((msecsTime - queue->phaseMilliSeconds) % queue->msecsResolution); msecsResult = (c_ulonglong)(msecsTime - msecsLeftOver); MSEC_TO_TIME(msecsResult, sendBefore); } while ((currentMarker != NULL) && (!found)) { eq = c_timeCompare(sendBefore, currentMarker->sendBefore); switch (eq) { case C_GT: currentMarkerPtr = ¤tMarker->next; currentMarker = *currentMarkerPtr; break; case C_EQ: if (priorityLookingFor < currentMarker->priority) { currentMarkerPtr = ¤tMarker->next; currentMarker = *currentMarkerPtr; } else { found = TRUE; if (priorityLookingFor == currentMarker->priority) { marker = currentMarker; } } break; case C_LT: found = TRUE; break; default: assert(FALSE); break; } } } else { if (currentMarker) { sendBefore = C_TIME_ZERO; if (c_timeIsZero(currentMarker->sendBefore)) { marker = currentMarker; } } } /* Insert after end of list */ if (marker == NULL) { newMarkerCreated = TRUE; if (queue->freeStatusMarkers == NULL) { marker = v_networkStatusMarker(c_new(queue->statusMarkerType)); } else { marker = queue->freeStatusMarkers; queue->freeStatusMarkers = marker->next; } if (marker != NULL) { marker->sendBefore = sendBefore; marker->priority = priorityLookingFor; marker->firstSample = NULL; marker->lastSample = NULL; marker->next = *currentMarkerPtr; /* no keep, transfer refCount */ if (marker->next == NULL) { queue->lastStatusMarker = marker; /* no keep, not reference counted */ } *currentMarkerPtr = marker; /* no keep, transfer refCount */ } else { OS_REPORT(OS_ERROR, "v_networkQueueWrite",0, "Failed to send message."); c_mutexUnlock(&queue->mutex); return FALSE; } } V_MESSAGE_STAMP(msg,readerLookupTime); assert(marker != NULL); if (queue->freeSamples == NULL) { newHolder = c_new(queue->sampleType); } else { newHolder = queue->freeSamples; queue->freeSamples = newHolder->next; } if (newHolder) { queue->currentMsgCount++; /* numberOfSamplesInserted & numberOfSamplesWaiting + stats*/ v_networkQueueStatisticsAdd(numberOfSamplesInserted,queue->statistics); v_networkQueueStatisticsCounterInc(numberOfSamplesWaiting,queue->statistics); newHolder->message = c_keep(msg); newHolder->entry = c_keep(entry); newHolder->sequenceNumber = sequenceNumber; newHolder->sender = sender; newHolder->sendTo = sendTo; newHolder->receiver = receiver; if (marker->lastSample != NULL) { newHolder->next = v_networkQueueSample(marker->lastSample)->next; /* no keep, transfer refCount */ v_networkQueueSample(marker->lastSample)->next = newHolder; /* no keep, transfer refCount */ } else { newHolder->next = marker->firstSample; /* no keep, transfer refCount */ marker->firstSample = newHolder; /* no keep, transfer refCount */ } marker->lastSample = newHolder; /* Write done, wake up waiters if needed */ if (wasEmpty && queue->threadWaiting) { if (sendNow || v_networkQueueHasExpiringData(queue)) { c_condBroadcast(&queue->cv); } } } else { OS_REPORT(OS_ERROR, "v_networkQueueWrite",0, "Failed to send message."); result = FALSE; } c_mutexUnlock(&queue->mutex); return result; }
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; }