v_result v_deliveryServiceEnable( v_deliveryService _this) { #if 0 v_kernel kernel; v_message builtinMsg; #endif v_subscriber subscriber; v_result result; if (_this) { result = V_RESULT_OK; subscriber = v_subscriber(v_reader(_this)->subscriber); v_subscriberAddReader(subscriber,v_reader(_this)); #if 0 kernel = v_objectKernel(_this); builtinMsg = v_builtinCreateSubscriptionInfo(kernel->builtin, _this); v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); c_free(builtinMsg); #endif } else { result = V_RESULT_ILL_PARAM; } return result; }
void v_publicDispose( v_public o) { assert(C_TYPECHECK(o,v_public)); if (o == NULL) { return; } switch(v_objectKind(o)) { case K_PARTICIPANT: v_participantDeinit(v_participant(o)); break; case K_PUBLISHER: v_publisherDeinit(v_publisher(o)); break; case K_SUBSCRIBER: v_subscriberDeinit(v_subscriber(o)); break; case K_WRITER: v_writerDeinit(v_writer(o)); break; case K_DATAREADER: v_dataReaderDeinit(v_dataReader(o)); break; case K_DELIVERYSERVICE:v_deliveryServiceDeinit(v_deliveryService(o)); break; case K_NETWORKREADER: v_networkReaderDeinit(v_networkReader(o)); break; case K_READER: v_readerDeinit(v_reader(o)); break; case K_GROUPQUEUE: v_groupQueueDeinit(v_groupQueue(o)); break; case K_TOPIC: v_topicDeinit(v_topic(o)); break; case K_ENTITY: break; case K_DOMAIN: v_partitionDeinit(v_partition(o)); break; case K_GROUP: v_groupDeinit(v_group(o)); break; case K_SERVICEMANAGER: /* Is never freed! */ break; case K_SPLICED: v_splicedDeinit(v_spliced(o)); break; case K_NETWORKING: case K_DURABILITY: case K_CMSOAP: case K_SERVICE: v_serviceDeinit(v_service(o)); break; case K_SERVICESTATE: /* Is never freed! */ break; case K_CONFIGURATION: break; case K_QUERY: OS_REPORT(OS_ERROR, "v_publicDispose failure", 0, "deinit of abstract class K_QUERY"); break; case K_DATAREADERQUERY: v_dataReaderQueryDeinit(v_dataReaderQuery(o)); break; case K_DATAVIEWQUERY: v_dataViewQueryDeinit(v_dataViewQuery(o)); break; case K_DATAVIEW: v_dataViewDeinit(v_dataView(o)); break; case K_WAITSET: v_waitsetDeinit(v_waitset(o)); break; case K_WRITERINSTANCE: v_writerInstanceDeinit(v_writerInstance(o)); break; case K_DATAREADERINSTANCE: v_dataReaderInstanceDeinit(v_dataReaderInstance(o)); break; case K_DATAVIEWINSTANCE: v_dataViewInstanceDeinit(v_dataViewInstance(o)); break; default: OS_REPORT_1(OS_ERROR,"v_publicDispose failed",0, "illegal entity kind (%d) specified",v_objectKind(o)); assert(FALSE); break; } c_free(o); }
c_iter v_partitionLookupSubscribers( v_partition partition) { c_iter participants; c_iter result; c_iter entities; c_iter partitions; v_participant participant; v_entity entity; v_entity partition2; result = NULL; participants = v_resolveParticipants(v_objectKernel(partition), "*"); participant = v_participant(c_iterTakeFirst(participants)); while (participant != NULL) { c_lockRead(&participant->lock); entities = c_select(participant->entities, 0); c_lockUnlock(&participant->lock); entity = v_entity(c_iterTakeFirst(entities)); while (entity != NULL) { if(v_objectKind(entity) == K_SUBSCRIBER) { partitions = v_subscriberLookupPartitions(v_subscriber(entity), v_partitionName(partition)); if (c_iterLength(partitions) > 0) { result = c_iterInsert(result, entity); /* transfer refcount */ } else { c_free(entity); } partition2 = v_entity(c_iterTakeFirst(partitions)); while (partition2 != NULL) { c_free(partition2); partition2 = v_entity(c_iterTakeFirst(partitions)); } c_iterFree(partitions); } /* entity is already free or refcount transferred to result */ entity = v_entity(c_iterTakeFirst(entities)); } c_iterFree(entities); c_free(participant); participant = v_participant(c_iterTakeFirst(participants)); } c_iterFree(participants); return result; }
static void getStatusMask( v_entity e, c_voidp arg) { c_long *mask = (c_long *)arg; if ( v_objectKind(e) == K_SUBSCRIBER ) { if ( !c_setWalk(v_subscriber(e)->readers, (c_action)readerHasDataAvailable, NULL) ) { *mask = V_EVENT_DATA_AVAILABLE; } else { *mask = 0; } } else { *mask = v_statusGetMask(e->status); } }
static c_bool connectNewGroup( c_object o, c_voidp arg) { switch (v_objectKind(o)) { case K_PUBLISHER: v_publisherConnectNewGroup(v_publisher(o), (v_group)arg); break; case K_SUBSCRIBER: v_subscriberConnectNewGroup(v_subscriber(o), (v_group)arg); break; default: /* Other entities do not connect */ break; } return TRUE; }
void v_readerFree( v_reader r) { assert(C_TYPECHECK(r,v_reader)); if (r->subscriber != NULL) { v_subscriberRemoveReader(v_subscriber(r->subscriber),r); c_mutexLock(&(v_observer(r)->mutex)); r->subscriber = NULL; c_mutexUnlock(&(v_observer(r)->mutex)); } /* Free all entries */ v_readerWalkEntries(r, entryFree, NULL); /* Call inherited free */ v_collectionFree(v_collection(r)); }
c_ulong v_networkReaderCreateQueue( v_networkReader reader, c_ulong queueSize, c_ulong priority, c_bool reliable, c_bool P2P, c_time resolution, c_bool useAsDefault, const c_char *name) { c_ulong result = 0; v_networkQueue queue; v_networkReaderStatistics s; v_networkQueueStatistics nqs; v_networkingStatistics nws; v_networkChannelStatistics ncs; v_kernel kernel; v_networking n; v_participant p; kernel = v_objectKernel(reader); if (reader->nofQueues < NW_MAX_NOF_QUEUES) { p = v_participant(v_subscriber(v_reader(reader)->subscriber)->participant); if ((v_objectKind(p) == K_NETWORKING) && (v_isEnabledStatistics(kernel, V_STATCAT_NETWORKING))) { nqs = v_networkQueueStatisticsNew(kernel,name); ncs = v_networkChannelStatisticsNew(kernel,name); } else { nqs = NULL; ncs = NULL; } queue = v_networkQueueNew(c_getBase((c_object)reader), queueSize, priority, reliable, P2P, resolution, nqs); if (queue != NULL) { reader->queues[reader->nofQueues] = queue; reader->nofQueues++; result = reader->nofQueues; /* insert statistics */ if (nqs != NULL) { s = v_networkReaderStatistics(v_entityStatistics(v_entity(reader))); if (s != NULL) { s->queues[s->queuesCount]=nqs; s->queuesCount++; } } if ((useAsDefault) || (reader->defaultQueue == NULL)){ c_free(reader->defaultQueue); reader->defaultQueue = c_keep(queue); } if (ncs != NULL) { /* add channel to the networking statistics also */ n = v_networking(p); nws = (v_networkingStatistics)v_entity(n)->statistics; nws->channels[nws->channelsCount]=ncs; nws->channelsCount++; } } } else { OS_REPORT_1(OS_ERROR, "v_networkReaderCreateQueue", 0, "Maximum number of network queues (%d) exceeded, " "new queue not created", NW_MAX_NOF_QUEUES); } return result; }
static void nw_channelWriterMain( v_entity e, c_voidp arg) { v_networkReader reader; nw_channelWriter channelWriter; c_bool newGroupAvailable; v_networkQueue qosQueue; v_networkReaderWaitResult waitResult; c_long bytesWritten; /* Total number of messages sent to the network */ c_ulong writtenCountMessages; /* Total number of bytes sent to the network */ c_ulong writtenCountBytes; /* Total number of bytes sent to the network during one burst */ c_ulong writtenCountBytesThisBurst; /* Number of message sent to the network after last report */ c_ulong writtenCountMessagesReport; v_message message; v_networkReaderEntry entry; c_ulong sequenceNumber; v_gid sender; c_bool sendTo; v_gid receiver; c_time sendBefore; c_ulong priority; c_bool more = TRUE; c_bool slowingDown; c_ulong timeoutCount; nw_signedLength credits; v_networking n; NW_STRUCT(plugSendStatistics) pss = {0,0,0,0,0,0,0,0,0,0, {0, {{0,0}, 0}, {{0,0}, 0}, {0.0,0}}, {0, {{0,0}, 0}, {{0,0}, 0}, {0.0,0}}, 0,0,0}; v_fullCounterInit(&(pss.adminQueueAcks)); v_fullCounterInit(&(pss.adminQueueData)); reader = v_networkReader(e); channelWriter = (nw_channelWriter)arg; /* This line is needed as long as the discovery channel is not yet implemented */ writtenCountBytesThisBurst = 0; writtenCountMessages = 0; writtenCountBytes = 0; writtenCountMessagesReport = 0; slowingDown = FALSE; timeoutCount = 0; credits = 0; while (!(int)nw_runnableTerminationRequested((nw_runnable)channelWriter)) { /* Wait for data on the reader */ if (!slowingDown) { waitResult = v_networkReaderWait(reader, channelWriter->queueId, &qosQueue); } else { waitResult = v_networkReaderWaitDelayed(reader, channelWriter->queueId, &qosQueue); NW_CONFIDENCE(waitResult & (V_WAITRESULT_TIMEOUT | V_WAITRESULT_TRIGGERED)); } if ((waitResult & V_WAITRESULT_TRIGGERED) && (!nw_runnableTerminationRequested((nw_runnable)channelWriter))) { /* If necessary, check if any new groups need to be added */ newGroupAvailable = nw_channelUserRetrieveNewGroup( (nw_channelUser)channelWriter, &entry); while (newGroupAvailable) { /* Create a new channel on the network */ /* No, do not call any function. With the new design, * a channelWriter does not need to know anything about this * new group. Maybe at a later stage. */ /* nw_channelAddGroup((nw_channel)channelWriter->sendChannel, entry); */ /* And notify we are connected */ v_networkReaderEntryNotifyConnected(entry,channelWriter->serviceName); newGroupAvailable = nw_channelUserRetrieveNewGroup( (nw_channelUser)channelWriter, &entry); } } /* Resend data should also obey max_burst_size * Each clocktick, the remaining credits of the last period and a * third of the new max_burst_size budget may be used for resend data. * The rest of the budget is assigned after that, and can be used to * flush stored buffers of send fresh data. */ if (waitResult & V_WAITRESULT_TIMEOUT) { /* * The periodic action is needed for every clocktick. * This will also update the credits, for the amount of bandwidth * available in the coming period. */ /*stat update routine */ n = v_networking(v_subscriber(v_reader(reader)->subscriber)->participant); /* update statistics */ if (v_entity(n)->statistics) { if (!pss.enabled) { pss.enabled =1; } /* sync plug stats */ nw_updatePlugSendStatistics(&pss,channelWriter); nw_SendChannelUpdate(v_networkingStatistics(v_entity(n)->statistics)->channels[channelWriter->stat_channel_id],channelWriter->scs); } nw_sendChannelPeriodicAction(channelWriter->sendChannel,&credits,&pss); /*struc call*/ /* A flush is needed if we are slowing down. */ if (slowingDown) { /* The return value is true is all data has been sent. * Afterwards, credits will contain the new amount of allowed * bytes. * We are using a special flush function here that flushes full * buffers only */ slowingDown = !nw_sendChannelFlush(channelWriter->sendChannel, FALSE, &credits, &pss); } } if ((waitResult & V_WAITRESULT_MSGWAITING) && !slowingDown) { /* Messages are waiting... */ writtenCountBytesThisBurst = 0; more= TRUE; while (more && ((nw_signedLength)writtenCountBytesThisBurst <= credits)) { /* Take any new messages */ v_networkQueueTakeFirst(qosQueue, &message, &entry, &sequenceNumber, &sender, &sendTo, &receiver, &sendBefore, &priority, &more); NW_CONFIDENCE(message != NULL); NW_CONFIDENCE(entry != NULL); if (!(NW_SECURITY_CHECK_FOR_PUBLISH_PERMISSION_OF_SENDER_ON_SENDER_SIDE(entry))) { bytesWritten = 0; /* indicates that nothing has been written */ NW_REPORT_WARNING_2( "nw_channelWriterMain", "Channel \"%s\" could not deliver message 0x%x : message dropped!", ((nw_runnable)channelWriter)->name, message); } else { bytesWritten = nw_sendChannelWrite(channelWriter->sendChannel, entry, message, &credits ,&pss); /* stat struc plug vars */ if (bytesWritten == 0) { NW_REPORT_WARNING_2( "nw_channelWriterMain", "Channel \"%s\" could not deliver message 0x%x : message dropped!", ((nw_runnable)channelWriter)->name, message); } /*numberOfMessagesSent stats*/ if (pss.enabled) { channelWriter->scs->numberOfMessagesSent++; } assert( bytesWritten > 0); /* if permission grantedm the value must be greater 0 */ } writtenCountBytesThisBurst += bytesWritten; #define NW_IS_BUILTIN_DOMAINNAME(name) ((int)(name)[0] == (int)'_') /* Do not trace for internal partitions */ if (bytesWritten>0 && /* might be 0 if access control refuses write permission */ !NW_IS_BUILTIN_DOMAINNAME( v_partitionName(v_groupPartition(entry->group)))) { #undef NW_IS_BUILTIN_DOMAINNAME writtenCountBytes += bytesWritten; writtenCountMessages++; writtenCountMessagesReport++; if (writtenCountMessagesReport == channelWriter->reportInterval) { NW_TRACE_3(Send, 3, "Channel %s: %u messages (%u bytes) " "taken from queue and written to network", ((nw_runnable)channelWriter)->name, writtenCountMessages, writtenCountBytes); writtenCountMessagesReport = 0; } NW_TRACE_3(Send, 4, "Channel %s: data message taken from queue, " "and written to network (partition = %s, topic = %s)", ((nw_runnable)channelWriter)->name, v_partitionName(v_groupPartition(entry->group)), v_topicName(v_groupTopic(entry->group))); } c_free(message); c_free(entry); } slowingDown = !nw_sendChannelFlush(channelWriter->sendChannel, TRUE, &credits, &pss); } } NW_TRACE_3(Send, 2, "Channel %s: %u messages (%u bytes) taken from queue and " "written to network", ((nw_runnable)channelWriter)->name, writtenCountMessages, writtenCountBytes); }
void v_participantFree( v_participant p) { v_message builtinMsg; v_participant found; v_entity e; v_kernel kernel; /* Not clear yet why builtin subscriber lock and participant lock are not taken now? * Also not clear why observer lock is not taken but is freed at the end! */ if (p != NULL) { assert(C_TYPECHECK(p,v_participant)); kernel = v_objectKernel(p); if (!v_observableRemoveObserver(v_observable(kernel),v_observer(p), NULL)) { if (v_participantName(p) != NULL) { OS_REPORT_1(OS_WARNING,"v_participantFree",0, "Participant '%s' cannot disconnect from Kernel events", v_participantName(p)); } else { OS_REPORT(OS_WARNING,"v_participantFree",0, "Participant cannot disconnect from Kernel events"); } } builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); v_writeDisposeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); v_unregisterBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); if (p->builtinSubscriber) { v_subscriberFree(p->builtinSubscriber); p->builtinSubscriber = NULL; } while ((e = c_take(p->entities)) != NULL) { switch (v_objectKind(e)) { case K_PUBLISHER: v_publisherFree(v_publisher(e)); break; case K_SUBSCRIBER: v_subscriberFree(v_subscriber(e)); break; case K_WAITSET: v_waitsetFree(v_waitset(e)); break; default: OS_REPORT_1(OS_WARNING,"Kernel Participant",0, "Illegal contained object (%s)", v_participantName(p)); break; } c_free(e); /* deref o since c_take will not */ } found = v_removeParticipant(kernel,p); assert(found == p); c_free(found); v_observerFree(v_observer(p)); } }
d_readerRequest d_readerRequestNew( d_admin admin, v_handle source, c_char* filter, c_char** filterParams, c_long filterParamsCount, struct v_resourcePolicy resourceLimits, c_time minSourceTimestamp, c_time maxSourceTimestamp) { d_readerRequest request; c_long i; v_handleResult handleResult; v_reader vreader, *vreaderPtr; c_iter partitions; v_partition partition; v_topic topic; d_group dgroup; c_char *topicName; d_quality quality; request = d_readerRequest(os_malloc(C_SIZEOF(d_readerRequest))); if(request){ d_lockInit(d_lock(request), D_READER_REQUEST, d_readerRequestDeinit); request->admin = admin; request->readerHandle.index = source.index; request->readerHandle.serial = source.serial; request->readerHandle.server = source.server; request->requests = d_tableNew(d_chainCompare, d_chainFree); if(filter){ request->filter = os_strdup(filter); } else { request->filter = NULL; } request->resourceLimits = resourceLimits; request->minSourceTimestamp = minSourceTimestamp; request->maxSourceTimestamp = maxSourceTimestamp; request->filterParamsCount = filterParamsCount; if(filterParamsCount > 0){ request->filterParams = (c_char**)(os_malloc( filterParamsCount*sizeof(c_char*))); for(i=0; i<filterParamsCount; i++){ request->filterParams[i] = os_strdup(filterParams[i]); } } else { request->filterParams = NULL; } request->groups = d_tableNew(d_groupCompare, d_groupFree); handleResult = v_handleClaim(source, (v_object*)(vreaderPtr = &vreader)); if(handleResult == V_HANDLE_OK){ if(v_object(vreader)->kind == K_DATAREADER){ topic = v_dataReaderGetTopic(v_dataReader(vreader)); topicName = v_entity(topic)->name; partitions = ospl_c_select(v_subscriber(vreader->subscriber)->partitions->partitions, 0); partition = v_partition(c_iterTakeFirst(partitions)); while(partition){ quality.seconds = 0; quality.nanoseconds = 0; dgroup = d_groupNew( v_entity(partition)->name, topicName, topic->qos->durability.kind, D_GROUP_KNOWLEDGE_UNDEFINED, quality); d_tableInsert(request->groups, dgroup); c_free(partition); partition = v_partition(c_iterTakeFirst(partitions)); } c_free(topic); } else { d_readerRequestFree(request); request = NULL; } v_handleRelease(source); } else { d_readerRequestFree(request); request = NULL; } } return request; }
v_subscriber v_subscriberNew( v_participant p, const c_char *name, v_subscriberQos qos, c_bool enable) { v_kernel kernel; v_subscriber s; v_subscriberQos q; v_entity found; v_accessMode access; kernel = v_objectKernel(p); /* ES, dds1576: If a partition policy was provided then we need to verify * if the partition policy does not contain any partition expressions for * which read access is not allowed. * If read access is not allowed for one of the partitions listed in the * partition policy of the qos, then the subscriber will not be created at * all. */ if(qos && qos->partition) { access = v_kernelPartitionAccessMode(kernel, qos->partition); } else { access = V_ACCESS_MODE_READ_WRITE;/* default */ } if(access == V_ACCESS_MODE_READ_WRITE || access == V_ACCESS_MODE_READ) { q = v_subscriberQosNew(kernel,qos); if (q != NULL) { s = v_subscriber(v_objectNew(kernel,K_SUBSCRIBER)); v_observerInit(v_observer(s),name, NULL, enable); s->qos = q; c_mutexInit(&s->sharesMutex, SHARED_MUTEX); if (q->share.enable) { v_lockShares(kernel); found = v_addShareUnsafe(kernel,v_entity(s)); if (found != v_entity(s)) { /* Make sure to set the partition list to NULL, because * v_publicFree will cause a crash in the v_subscriberDeinit * otherwise. */ s->partitions = NULL; /*v_publicFree to free reference held by the handle server.*/ v_publicFree(v_public(s)); /*Now free the local reference as well.*/ c_free(s); pa_increment(&(v_subscriber(found)->shareCount)); v_unlockShares(kernel); return c_keep(found); } s->shares = c_tableNew(v_kernelType(kernel,K_READER), "qos.share.name"); } else { s->shares = NULL; } s->shareCount = 1; s->partitions = v_partitionAdminNew(kernel); s->readers = c_setNew(v_kernelType(kernel,K_READER)); if (q->share.enable) { s->participant = kernel->builtin->participant; } else { s->participant = p; } c_lockInit(&s->lock,SHARED_LOCK); v_participantAdd(v_participant(s->participant),v_entity(s)); if (q->share.enable) { v_unlockShares(kernel); } if (enable) { v_subscriberEnable(s); } } else { OS_REPORT(OS_ERROR, "v_subscriberNew", 0, "Subscriber not created: inconsistent qos"); s = NULL; } } else { OS_REPORT(OS_ERROR, "v_subscriberNew", 0, "Subscriber not created: Access rights for one of the partitions listed in the partition list was not sufficient (i.e. read or readwrite)."); s = NULL; } return s; }