void v_subscriberUnSubscribe( v_subscriber s, const c_char *partitionExpr) { v_partition d; v_dataReaderConnectionChanges arg; v_partitionPolicy old; assert(s != NULL); assert(C_TYPECHECK(s,v_subscriber)); arg.addedPartitions = NULL; c_lockWrite(&s->lock); arg.removedPartitions = v_partitionAdminRemove(s->partitions, partitionExpr); old = s->qos->partition; s->qos->partition = v_partitionPolicyRemove(old, partitionExpr, c_getBase(c_object(s))); c_free(old); c_setWalk(s->readers, qosChangedAction, &arg); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); } c_iterFree(arg.removedPartitions); c_lockUnlock(&s->lock); }
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); }
static void deliveryServiceUnSubscribe( void *o, void *arg) { v_partition p = v_partition(o); v_deliveryServiceEntry e = v_deliveryServiceEntry(arg); v_kernel kernel; v_group g; c_value params[2]; c_iter list; assert(C_TYPECHECK(e,v_deliveryServiceEntry)); assert(C_TYPECHECK(p,v_partition)); params[0] = c_objectValue(p); params[1] = c_objectValue(e->topic); kernel = v_objectKernel(e); list = v_groupSetSelect(kernel->groupSet, "partition = %0 and topic = %1", params); while ((g = c_iterTakeFirst(list)) != NULL) { v_groupRemoveEntry(g,v_entry(e)); c_free(g); } c_iterFree(list); }
v_partition v_partitionNew( v_kernel kernel, const c_char *name, v_partitionQos qos) { v_partition partition, found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(name != NULL); assert(v_partitionExpressionIsAbsolute(name)); partition = v_partition(v_objectNew(kernel,K_DOMAIN)); v_entityInit(v_entity(partition),name, NULL, TRUE); found = v_addPartition(kernel,partition); if (found != partition) { v_partitionFree(partition); c_free(partition); /* v_partitionFree has removed all dependancies, now delete local reference */ partition = c_keep(found); /* this one will be returned, so a keep is required */ } return partition; }
void v_subscriberConnectNewGroup( v_subscriber s, v_group g) { c_bool connect; c_iter addedPartitions; v_partition d; c_lockWrite(&s->lock); connect = v_partitionAdminFitsInterest(s->partitions, g->partition); if (connect) { addedPartitions = v_partitionAdminAdd(s->partitions, v_partitionName(g->partition)); d = v_partition(c_iterTakeFirst(addedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(addedPartitions)); } c_iterFree(addedPartitions); c_setWalk(s->readers, (c_action)v_readerSubscribeGroup, g); } else { /* * Check if group fits interest. This extra steps are needed because * the groupActionStream does not create the groups that match the * subscriber qos partition expression on creation. It only needs to * connect to new groups once they are created. This is a different * approach then for a data reader. */ /* * Because already existing partitions are created and added to the * subscriber of the groupActionStream at creation time, these * partitions can be resolved from the subscriber. This is necessary to * determine whether the groupActionStream should connect to the new * group or if it is already connected. */ if (v_partitionAdminExists(s->partitions, v_partitionName(g->partition))) { c_setWalk(s->readers, (c_action)notifyGroupQueues, g); } } c_lockUnlock(&s->lock); }
static c_bool unsubscribe( c_object entry, c_voidp partition) { v_partition p = v_partition(partition); v_deliveryServiceEntry e = v_deliveryServiceEntry(entry); deliveryServiceUnSubscribe(p, e); return TRUE; }
static void addPartition( void *o, c_iterActionArg arg) { v_partition p = v_partition(o); c_table t = (c_table)arg; v_partition found; found = c_tableInsert(t, p); if (found != p) { c_free(found); } }
static c_bool resolvePartitions( c_object o, c_voidp arg) { v_partitionInterest di = v_partitionInterest(o); struct resolvePartitionsArg *a = (struct resolvePartitionsArg *)arg; c_iter list; v_partition d; list = v_resolvePartitions(a->kernel, di->expression); d = v_partition(c_iterTakeFirst(list)); while (d != NULL) { *(a->partitions) = c_iterInsert(*(a->partitions), d); /* The reference is transferred from list to a->partitions, * so no c_free(d). */ d = v_partition(c_iterTakeFirst(list)); } c_iterFree(list); return TRUE; /* never break the walk */ }
static void removePartition( void *o, c_iterActionArg arg) { v_partition p = v_partition(o); c_table t = (c_table)arg; v_partition found; found = c_tableRemove(t, p, NULL, NULL); /* 'found' might be NULL, since partitions are only added when to this * administration when a group exists for that partition */ c_free(found); }
static c_bool checkPartitionInterest( c_object o, c_voidp arg) { v_partitionInterest partitionInterest = (v_partitionInterest)o; v_partition partition = v_partition(arg); c_bool result = TRUE; if (v_partitionStringMatchesExpression(v_partitionName(partition), partitionInterest->expression)) { result = FALSE; } return result; }
static c_bool updatePartitions( c_object o, c_voidp arg) { v_partition d = v_partition(o); struct updatePartitionsArg *a = (struct updatePartitionsArg *)arg; if (c_iterContains(*(a->addPartitions), (void *)d)) { c_iterTake(*(a->addPartitions), (void *)d); /* remove since we already know the partition */ c_free(d); } else { /* add to remove list, we are no longer interested */ *(a->removePartitions) = c_iterInsert(*(a->removePartitions), c_keep(d)); } return TRUE; /* never break the walk */ }
static void deliveryServiceSubscribe( void *o, void *arg) { v_partition p = v_partition(o); v_deliveryServiceEntry e = v_deliveryServiceEntry(arg); v_kernel kernel; v_group g; assert(C_TYPECHECK(e,v_deliveryServiceEntry)); assert(C_TYPECHECK(p,v_partition)); kernel = v_objectKernel(e); g = v_groupSetCreate(kernel->groupSet,p,e->topic); if(v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ_WRITE || v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ) { v_groupAddEntry(g,v_entry(e)); } c_free(g); }
static c_bool v__partitionAdminRemove( v_partitionAdmin da, const char *partitionName, v_partition *partitionRemoved) { c_bool result; v_partition partition, found; q_expr expr; c_collection q; c_iter list; c_value params[1]; assert(v_partitionExpressionIsAbsolute(partitionName)); expr = (q_expr)q_parse("name like %0"); params[0] = c_stringValue((char *)partitionName); q = c_queryNew(da->partitions, expr, params); q_dispose(expr); list = ospl_c_select(q,0); assert(c_iterLength(list) <= 1); partition = v_partition(c_iterTakeFirst(list)); if (partition) { found = c_tableRemove(da->partitions, partition, NULL, NULL); *partitionRemoved = found; c_free(partition); result = TRUE; } else { *partitionRemoved = NULL; result = FALSE; } c_free(q); c_iterFree(list); return result; }
void v_groupStreamNotify( v_groupStream stream, v_event e, c_voidp userData) { struct groupConnected data; c_iter partitions; c_bool interested; v_partition partition, found; OS_UNUSED_ARG(userData); assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); if (e) { if (e->kind == V_EVENT_NEW_GROUP) { v_observerLock(v_observer(stream)); /* * Check if group fits interest. This extra steps are needed because * the groupActionStream does not create the groups that match the * subscriber qos partition expression on creation. It only needs to * connect to new groups once they are created. This is a different * approach then for a data reader. */ partition = v_group(e->userData)->partition; /* * Because already existing partitions are created and added to the * subscriber of the groupActionStream at creation time, these * partitions can be resolved from the subscriber. This is necessary to * determine whether the groupActionStream should connect to the new * group or if it is already connected. */ partitions = v_subscriberLookupPartitions(v_reader(stream)->subscriber, v_partitionName(partition)); interested = FALSE; found = v_partition(c_iterTakeFirst(partitions)); while(found){ if(interested == FALSE){ if(strcmp(v_partitionName(partition), v_partitionName(found)) == 0){ interested = TRUE; } } c_free(found); found = v_partition(c_iterTakeFirst(partitions)); } c_iterFree(partitions); if(interested == TRUE){ /* * This means the group is interesting for this * groupActionStream. Now I have to check if the stream is already * connected to this group, because we wouldn't want to connect * multiple times to one single group. */ data.connected = FALSE; data.group = v_group(e->userData); c_walk(stream->groups, (c_action)isGroupConnected, &data); if(data.connected == FALSE){ /* * The stream is not connected to the group yet, so connect now. */ v_groupStreamSubscribeGroup(stream, v_group(e->userData)); } } v_observerUnlock(v_observer(stream)); } } return; }
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_result v_subscriberSetQos( v_subscriber s, v_subscriberQos qos) { v_result result; v_qosChangeMask cm; v_dataReaderConnectionChanges arg; v_partition d; v_accessMode access; assert(s != NULL); arg.addedPartitions = NULL; arg.removedPartitions = NULL; c_lockWrite(&s->lock); /* ES, dds1576: When the QoS is being set we have to verify that the partitions * listed in the qos do not have an invalid access mode set. For a subscriber * an invalid mode is characterized as 'write' mode. If the partitionAccess * check returns ok, then everything continue as normal. If the * partitionAccess check returns something else, then the setQos operation * is aborted. Please see the partitionAccess check operation to know when * a partition expression is not allowed. */ if(qos && qos->partition) { access = v_kernelPartitionAccessMode(v_objectKernel(s), qos->partition); } else { access = V_ACCESS_MODE_READ_WRITE;/* default */ } if(access == V_ACCESS_MODE_READ_WRITE || access == V_ACCESS_MODE_READ) { result = v_subscriberQosSet(s->qos, qos, v_entity(s)->enabled, &cm); if ((result == V_RESULT_OK) && (cm != 0)) { c_lockUnlock(&s->lock); /* since creation builtin topic might lock subscriber again. */ if (cm & V_POLICY_BIT_PARTITION) { /* partition policy has changed! */ v_partitionAdminSet(s->partitions, s->qos->partition, &arg.addedPartitions, &arg.removedPartitions); } c_setWalk(s->readers, qosChangedAction, &arg); d = v_partition(c_iterTakeFirst(arg.addedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(arg.addedPartitions)); } c_iterFree(arg.addedPartitions); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); } c_iterFree(arg.removedPartitions); } else { c_lockUnlock(&s->lock); } } else { result = V_RESULT_PRECONDITION_NOT_MET; c_lockUnlock(&s->lock); } return result; }