v_dataViewSample v_dataViewSampleNew( v_dataViewInstance instance, v_readerSample masterSample) { v_dataView dataView; v_dataViewSample sample; assert(instance != NULL); assert(masterSample != NULL); assert(C_TYPECHECK(masterSample,v_readerSample)); dataView = v_dataView(instance->dataView); #ifdef _EXTENT_ sample = v_dataViewSample(c_extentCreate(dataView->sampleExtent)); #else sample = v_dataViewSample(c_new(dataView->sampleType)); #endif if (sample) { v_readerSample(sample)->instance = (c_voidp)instance; v_readerSample(sample)->sampleState = 0; v_dataViewSampleList(sample)->next = NULL; v_dataViewSampleList(sample)->prev = NULL; sample->prev = NULL; v_dataViewSampleTemplate(sample)->sample = c_keep(masterSample); } else { OS_REPORT(OS_ERROR, "v_dataViewSampleNew",0, "Failed to allocate v_dataViewSample."); } return sample; }
void v_dataReaderSampleFree( v_dataReaderSample sample) { v_dataReaderInstance instance; v_index index; v_dataReader dataReader; v_message message; if (sample) { assert(C_TYPECHECK(sample, v_dataReaderSample)); if (c_refCount(sample) == 1) { /* Free the slave-samples as well */ instance = v_readerSample(sample)->instance; index = v_index(instance->index); dataReader = v_dataReader(index->reader); if (!v_readerSampleTestState(sample,L_READ)) { dataReader->notReadCount--; } #ifdef _SL_ if (dataReader->cachedSampleCount < 1000) { message = v_dataReaderSampleMessage(sample); c_free(message); v_dataReaderSampleTemplate(sample)->message = NULL; sample->prev = dataReader->cachedSample; dataReader->cachedSample = sample; dataReader->cachedSampleCount++; #else if (dataReader->cachedSample == NULL) { dataReader->cachedSample = sample; message = v_dataReaderSampleMessage(sample); c_free(message); v_dataReaderSampleTemplate(sample)->message = NULL; #endif } else { c_free(sample); } } else { c_free(sample); } } } void v_dataReaderSampleRemoveFromLifespanAdmin( v_dataReaderSample sample) { v_dataReaderInstance instance; v_index index; if (sample) { assert(C_TYPECHECK(sample, v_dataReaderSample)); instance = v_readerSample(sample)->instance; index = v_index(instance->index); v_lifespanAdminRemove(v_dataReaderEntry(index->entry)->lifespanAdmin, v_lifespanSample(sample)); } }
void v_dataReaderSampleEmptyViews( v_dataReaderSample sample) { v_dataViewSampleList viewSample; assert(sample != NULL); assert(C_TYPECHECK(sample, v_dataReaderSample)); viewSample = v_readerSample(sample)->viewSamples; while (viewSample != NULL) { v_dataViewSampleListRemove(viewSample); v_dataViewSampleRemove(v_dataViewSample(viewSample)); viewSample = v_readerSample(sample)->viewSamples; } }
void v_dataViewInstanceWalkSamples( v_dataViewInstance instance, v_readerSampleAction action, c_voidp arg) { v_dataViewSample sample; c_bool proceed = TRUE; assert(C_TYPECHECK(instance,v_dataViewInstance)); CHECK_INSTANCE(instance); if (instance == NULL) { return; } if (instance->sampleCount == 0) { return; } sample = v_dataViewInstanceTemplate(instance)->sample; while ((sample != NULL) && (proceed == TRUE)) { proceed = action(v_readerSample(sample),arg); sample = sample->prev; } CHECK_INSTANCE(instance); }
void v_dataViewSampleRemove( v_dataViewSample sample) { v_dataViewInstance instance; assert(C_TYPECHECK(sample,v_dataViewSample)); instance = v_dataViewInstance(v_readerSample(sample)->instance); CHECK_INSTANCE(instance); if (instance->sampleCount > 1) { if (sample->next != NULL) { v_dataViewSample(sample->next)->prev = sample->prev; } else { v_dataViewInstanceTemplate(instance)->sample = sample->prev; } if (sample->prev != NULL) { v_dataViewSample(sample->prev)->next = sample->next; } sample->prev = NULL; sample->next = NULL; c_free(sample); } instance->sampleCount--; if (instance->sampleCount > 0) { CHECK_INSTANCE(instance); } else { CHECK_ZERO_INSTANCE(instance); } }
v_dataViewInstance v_dataViewInstanceNew( v_dataView dataView, v_dataViewSample viewSample) { v_dataViewInstance instance; assert(dataView); assert(viewSample); assert(C_TYPECHECK(dataView,v_dataView)); assert(C_TYPECHECK(viewSample,v_dataViewSample)); instance = v_dataViewInstance(c_new(dataView->instanceType)); if (instance) { v_object(instance)->kernel = v_objectKernel(dataView); v_objectKind(instance) = K_DATAVIEWINSTANCE; v_instanceInit(v_instance(instance), v_entity(dataView)); viewSample->next = viewSample; v_dataViewInstanceTemplate(instance)->sample = viewSample; instance->sampleCount = 1; v_stateSet(v_instanceState(instance),L_NEW); v_stateClear(v_readerSample(viewSample)->sampleState,L_READ); assert(C_TYPECHECK(instance,v_dataViewInstance)); CHECK_INSTANCE(instance); } else { OS_REPORT(OS_FATAL, OS_FUNCTION, V_RESULT_INTERNAL_ERROR, "Failed to allocate v_dataViewInstance"); assert(FALSE); } return instance; }
static u_result handlePublication( u_dataReader dataReader, c_long dataOffset, u_dataReader pDataReader, c_long pDataOffset) { v_dataReaderSample sample; u_result result; v_state state; v_message msg; struct v_publicationInfo *data; in_writer writer; in_participant participant; sample = NULL; result = u_dataReaderTake(dataReader, takeOne, &sample); while(sample && (result == U_RESULT_OK)){ state = v_readerSample(sample)->sampleState; msg = v_dataReaderSampleMessage(sample); data = (struct v_publicationInfo *)(C_DISPLACE(msg, dataOffset)); os_mutexLock (&gluelock); if(v_stateTest(state, L_DISPOSED)){ writer = in_writerLookup(&data->key); if(writer){ in_writerFree(writer, NULL); } else { nn_log (LC_WARNING, "handlePublication: disposed writer not found\n"); /*abort();*/ } } else { participant = in_participantLookup(&(data->participant_key)); if(!participant){ result = handleParticipant(pDataReader, pDataOffset, 1); if(result == U_RESULT_OK){ participant = in_participantLookup(&(data->participant_key)); } } if(participant){ in_writerNew(participant, data); } else { nn_log (LC_ERROR, "handlePublication: participant not found\n"); result = U_RESULT_INTERNAL_ERROR; /*abort();*/ } } os_mutexUnlock (&gluelock); c_free(sample); sample = NULL; result = u_dataReaderTake(dataReader, takeOne, &sample); } return result; }
static void copySampleInfoView ( v_readerSample sample, v_message message, gapi_sampleInfo *to ) { v_state state; v_dataReaderSample master; v_dataViewInstance viewInstance; v_dataReaderInstance masterInstance; viewInstance = (v_dataViewInstance)sample->instance; master = v_dataReaderSample(v_dataViewSampleTemplate(sample)->sample); masterInstance = (v_dataReaderInstance)v_readerSampleInstance(master); state = v_readerSample(sample)->sampleState; if (v_stateTest (state, L_READ)) { to->sample_state = GAPI_READ_SAMPLE_STATE; } else { to->sample_state = GAPI_NOT_READ_SAMPLE_STATE; } if (v_stateTest (state, L_NEW)) { to->view_state = GAPI_NEW_VIEW_STATE; } else { to->view_state = GAPI_NOT_NEW_VIEW_STATE; } state = masterInstance->instanceState; to->instance_state = GAPI_ALIVE_INSTANCE_STATE; if (v_stateTest (state, L_NOWRITERS)) { to->instance_state = GAPI_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE; } if (v_stateTest (state, L_DISPOSED)) { to->instance_state = GAPI_NOT_ALIVE_DISPOSED_INSTANCE_STATE; } /* Data is always valid for views */ to->valid_data = TRUE; to->source_timestamp.sec = (gapi_long)(message->writeTime.seconds); to->source_timestamp.nanosec = (gapi_unsigned_long)(message->writeTime.nanoseconds); to->disposed_generation_count = master->disposeCount; to->no_writers_generation_count = master->noWritersCount; to->sample_rank = 0; to->generation_rank = 0; to->absolute_generation_rank = 0; to->instance_handle = u_instanceHandleNew(v_public(viewInstance)); to->publication_handle = u_instanceHandleFromGID(master->publicationHandle); to->reception_timestamp.sec = (gapi_long)(master->insertTime.seconds); to->reception_timestamp.nanosec = (gapi_unsigned_long)(master->insertTime.nanoseconds); }
void v_dataReaderSampleWipeViews( v_dataReaderSample sample) { v_dataViewSampleList viewSample; v_dataViewInstance instance; assert(sample != NULL); assert(C_TYPECHECK(sample, v_dataReaderSample)); viewSample = v_readerSample(sample)->viewSamples; while (viewSample != NULL) { instance = v_readerSample(viewSample)->instance; v_dataViewSampleListRemove(viewSample); v_dataViewSampleRemove(v_dataViewSample(viewSample)); v_dataViewInstanceRemove(instance); viewSample = v_readerSample(sample)->viewSamples; } }
void v_dataViewSampleListRemove( v_dataViewSampleList sample) { assert(C_TYPECHECK(sample,v_dataViewSampleList)); assert(v_dataViewInstance(v_readerSample(sample)->instance)->sampleCount > 0); CHECK_INSTANCE(v_dataViewInstance(v_readerSample(sample)->instance)); if (sample->next != NULL) { v_dataViewSampleList(sample->next)->prev = sample->prev; } if (sample->prev != NULL) { v_dataViewSampleList(sample->prev)->next = sample->next; } else { assert(v_dataViewSampleTemplate(sample)->sample->viewSamples == sample); v_dataViewSampleTemplate(sample)->sample->viewSamples = sample->next; } sample->prev = NULL; sample->next = NULL; CHECK_INSTANCE(v_dataViewInstance(v_readerSample(sample)->instance)); }
void v_dataReaderSampleRemoveFromLifespanAdmin( v_dataReaderSample sample) { v_dataReaderInstance instance; v_index index; assert(sample); assert(C_TYPECHECK(sample, v_dataReaderSample)); instance = v_readerSample(sample)->instance; index = v_index(instance->index); v_lifespanAdminRemove(v_dataReaderEntry(index->entry)->lifespanAdmin, v_lifespanSample(sample)); }
static v_actionResult readerActionView ( c_object o, c_voidp copyArg) { readerViewActionArg *info = (readerViewActionArg *) copyArg; v_readerSampleSeq *samples = info->samples; v_readerSample sample; v_actionResult result = V_PROCEED; gapi_unsigned_long i; if ( o ) { sample = v_readerSample(o); if (gapi_matchesReaderMask(o, &info->datareaderview->reader_mask)) { if ( !sampleSeqContains(samples, sample) ) { i = samples->_length; if ( v_readerSampleSeq_setLength(samples, i+1) ) { samples->_buffer[i] = c_keep(sample); c_keep(sample->instance); } else { info->result = GAPI_RETCODE_OUT_OF_RESOURCES; v_actionResultClear(result, V_PROCEED); } if ( samples->_length >= info->max ) { v_actionResultClear(result, V_PROCEED); } } } else { v_actionResultSet(result, V_SKIP); } } else { if ( samples->_length > 0 ) { determineSampleInfoView(info); for ( i = 0UL; i < samples->_length; i++ ) { c_free(samples->_buffer[i]->instance); c_free(samples->_buffer[i]); } } else { info->readerCopy(NULL, info->readerInfo); info->result = GAPI_RETCODE_NO_DATA; } v_actionResultClear(result, V_PROCEED); } return result; }
v_dataViewInstance v_dataViewInstanceNew( v_dataView dataView, v_readerSample sample) { v_dataViewInstance instance; v_dataViewSample viewSample; assert(dataView); assert(sample); assert(C_TYPECHECK(dataView,v_dataView)); assert(C_TYPECHECK(sample,v_readerSample)); instance = v_dataViewInstance(c_new(dataView->instanceType)); if (instance) { v_object(instance)->kernel = v_objectKernel(dataView); v_objectKind(instance) = K_DATAVIEWINSTANCE; instance->dataView = (c_voidp)dataView; viewSample = v_dataViewSampleNew(instance,sample); if (viewSample) { v_dataViewInstanceTemplate(instance)->sample = viewSample; viewSample->next = NULL; viewSample->prev = NULL; v_readerSampleAddViewSample(sample,viewSample); instance->sampleCount = 1; v_stateSet(instance->instanceState,L_NEW); v_stateClear(v_readerSample(viewSample)->sampleState,L_READ); assert(C_TYPECHECK(instance,v_dataViewInstance)); v_dataViewNotifyDataAvailable(dataView, viewSample); } CHECK_INSTANCE(instance); } else { OS_REPORT(OS_ERROR, "v_dataViewInstanceNew",0, "Failed to allocate v_dataViewInstancem"); assert(FALSE); } return instance; }
static u_result handleParticipant( u_dataReader dataReader, c_long dataOffset, int gluelockAlreadyHeld) { v_dataReaderSample sample; u_result result; v_state state; v_message msg; struct v_participantInfo *data; in_participant participant; sample = NULL; result = u_dataReaderTake(dataReader, takeOne, &sample); while(sample && (result == U_RESULT_OK)){ state = v_readerSample(sample)->sampleState; msg = v_dataReaderSampleMessage(sample); data = (struct v_participantInfo *)(C_DISPLACE(msg, dataOffset)); if (!gluelockAlreadyHeld) os_mutexLock (&gluelock); if(v_stateTest(state, L_DISPOSED)){ participant = in_participantLookup(&(data->key)); if(participant){ in_participantFree(participant, NULL); } } else { in_participantNew(data); } if (!gluelockAlreadyHeld) os_mutexUnlock (&gluelock); c_free(sample); sample = NULL; result = u_dataReaderTake(dataReader, takeOne, &sample); } 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; }
static void determineSampleInfoView ( readerViewActionArg *info) { gapi_unsigned_long i; v_readerSampleSeq *samples = info->samples; gapi_unsigned_long length; gapi_dataSampleSeq dataSamples; gapi_dataSample onePlaceBuffer; gapi_boolean onHeap = FALSE; gapi_boolean onStack = FALSE; assert(samples->_length > 0); length = samples->_length; if ( length == 1 ) { dataSamples._buffer = &onePlaceBuffer; } else if ( length < MAX_DATASAMPLESEQ_SIZE_ON_STACK ) { dataSamples._buffer = (gapi_dataSample *)os_alloca(length*sizeof(gapi_dataSample)); if ( dataSamples._buffer ) { onStack = TRUE; } else { dataSamples._buffer = (gapi_dataSample *)os_malloc(length*sizeof(gapi_dataSample)); onHeap = TRUE; } } else { dataSamples._buffer = (gapi_dataSample *)os_malloc(length*sizeof(gapi_dataSample)); onHeap = TRUE; } if ( dataSamples._buffer ) { dataSamples._length = length; dataSamples._maximum = length; dataSamples._release = FALSE; for ( i = 0; i < length; i++ ) { v_dataViewSampleTemplate viewSample = v_dataViewSampleTemplate(samples->_buffer[i]); v_dataReaderSampleTemplate sample = v_dataReaderSampleTemplate(viewSample->sample); v_message message = sample->message; dataSamples._buffer[i].data = (void *)C_DISPLACE(message, info->datareaderview->datareader->userdataOffset); copySampleInfoView(v_readerSample(viewSample), message, &dataSamples._buffer[i].info); } computeGenerationRanksView(samples, &dataSamples); info->readerCopy(&dataSamples, info->readerInfo); if ( onStack ) { os_freea(dataSamples._buffer); } else { if ( onHeap ) { os_free(dataSamples._buffer); } } } else { info->result = GAPI_RETCODE_OUT_OF_RESOURCES; } }
v_actionResult v_dataViewSampleReadTake( v_dataViewSample sample, v_readerSampleAction action, c_voidp arg, c_bool consume) { v_dataViewInstance instance; v_state state; v_state mask; v_actionResult result = 0; instance = v_dataViewSampleInstance(sample); state = v_instanceState(instance); mask = L_NEW | L_DISPOSED | L_NOWRITERS; /* Copy the value of instance state bits specified by the mask * to the sample state bits without affecting other bits. */ v_readerSampleSetState(sample,(state & mask)); v_readerSampleClearState(sample,(~state & mask)); /* If the status of the sample is READ by the previous read * operation and the flag is not yet set (specified by the * LAZYREAD flag) then correct the state before executing the * read action. */ if (v_readerSampleTestState(sample,L_LAZYREAD)) { v_readerSampleSetState(sample,L_READ); v_readerSampleClearState(sample,L_LAZYREAD); } /* An action routine is provided in case the sample needs to be returned * to the user. If an action routine is not provided, it means the sample * needs to be removed from the administration, so the reader should be * modified accordingly. That means the 'proceed' flag should be set in * that case. */ V_MESSAGE_STAMP(v_dataReaderSampleMessage(sample),readerReadTime); if (action) { /* Invoke the action routine with the typed sample. */ result = action(v_readerSample(sample), arg); } else { v_actionResultSet(result, V_PROCEED); } /* A sample is considered 'skipped' if the action routine invoked above * does not want to keep track of the sample (for example because it * didn't match its readerMasks). In that case, it sets the 'skip' flag * to true, which indicates that those samples should be considered * 'untouched' and therefore their instance and sample states should * not be modified. */ if (v_actionResultTestNot(result, V_SKIP)) { V_MESSAGE_STAMP(v_dataReaderSampleMessage(sample),readerCopyTime); V_MESSAGE_REPORT(v_dataReaderSampleMessage(sample), v_dataReaderInstanceDataReader(instance)); v_stateClear(v_instanceState(instance),L_NEW); if (!v_stateTest(v_readerSample(sample)->sampleState,L_READ)) { v_stateSet(v_readerSample(sample)->sampleState,L_LAZYREAD); } if (consume) { v_dataViewSampleListRemove(v_dataViewSampleList(sample)); v_dataViewSampleRemove(sample); } } return result; }
v_dataReaderSample v_dataReaderSampleNew( v_dataReaderInstance instance, v_message message) { v_dataReader dataReader; v_dataReaderSample sample; v_readerQos readerQos; v_index index; assert(instance != NULL); assert(C_TYPECHECK(message,v_message)); index = v_index(instance->index); dataReader = v_dataReader(index->reader); readerQos = v_reader(dataReader)->qos; if (dataReader->cachedSample != NULL) { sample = dataReader->cachedSample; /* Unfinished proto for cache size control * #define _SL_ */ #ifdef _SL_ dataReader->cachedSample = sample->prev; sample->prev = NULL; dataReader->cachedSampleCount--; #else dataReader->cachedSample = NULL; #endif } else { sample = v_dataReaderSample(c_extentCreate(dataReader->sampleExtent)); } v_readerSample(sample)->instance = (c_voidp)instance; v_readerSample(sample)->viewSamples = NULL; if ((message->transactionId != 0) && (v_reader(dataReader)->subQos->presentation.coherent_access)) { v_readerSample(sample)->sampleState = L_TRANSACTION; } else { v_readerSample(sample)->sampleState = 0; } #ifdef _NAT_ sample->insertTime = v_timeGet(); #else #define _INCORRECT_BUT_LOW_INSERT_LATENCY_ #ifdef _INCORRECT_BUT_LOW_INSERT_LATENCY_ if (v_timeIsZero(v_reader(dataReader)->qos->latency.duration)) { sample->insertTime = v_timeGet(); } else { sample->insertTime = message->allocTime; } #else sample->insertTime = v_timeGet(); #endif #endif if (readerQos->lifespan.used) { v_lifespanSample(sample)->expiryTime = c_timeAdd(sample->insertTime, readerQos->lifespan.duration); } else { v_lifespanSample(sample)->expiryTime = c_timeAdd(sample->insertTime, v_messageQos_getLifespanPeriod(message->qos)); } sample->disposeCount = instance->disposeCount; sample->noWritersCount = instance->noWritersCount; sample->publicationHandle = message->writerGID; sample->readId = 0; sample->prev = NULL; assert(message); v_dataReaderSampleTemplate(sample)->message = c_keep(message); v_lifespanAdminInsert(v_dataReaderEntry(index->entry)->lifespanAdmin, v_lifespanSample(sample)); dataReader->notReadCount++; return sample; }