/************************************************************** * Private functions **************************************************************/ static c_bool v__partitionAdminAdd( v_partitionAdmin da, const char *partitionName, v_partition *newPartition) { c_bool result = TRUE; v_partition partition, found; assert(v_partitionExpressionIsAbsolute(partitionName)); assert(newPartition != NULL); partition = v_partitionNew(v_objectKernel(da), partitionName, NULL); found = c_tableInsert(da->partitions, partition); if (found != partition) { c_free(partition); result = FALSE; *newPartition = NULL; } else { /* Do not free partition here because it is returned */ *newPartition = partition; } return result; }
u_partition u_partitionNew( u_participant p, const c_char *name, v_partitionQos qos) { u_partition _this = NULL; v_kernel ke = NULL; v_partition kd; u_result result; if (name == NULL) { name = "No partition specified"; } if (p != NULL) { result = u_entityWriteClaim(u_entity(u_participantDomain(p)),(v_entity*)(&ke)); if ((result == U_RESULT_OK) && (ke != NULL)) { kd = v_partitionNew(ke,name,qos); if (kd != NULL) { _this = u_entityAlloc(p,u_partition,kd,FALSE); if (_this != NULL) { result = u_partitionInit(_this); if (result != U_RESULT_OK) { OS_REPORT_1(OS_ERROR, "u_partitionNew", 0, "Initialisation failed. " "For Partition: <%s>.", name); u_partitionFree(_this); } } else { OS_REPORT_1(OS_ERROR, "u_partitionNew", 0, "Create proxy failed. " "For Partition: <%s>.", name); } c_free(kd); } else { OS_REPORT_1(OS_ERROR, "u_partitionNew", 0, "Create kernel entity failed. " "For Partition: <%s>", name); } result = u_entityRelease(u_entity(u_participantDomain(p))); } else { OS_REPORT_1(OS_WARNING, "u_partitionNew", 0, "Claim Participant failed. " "For Partition: <%s>", name); } } else { OS_REPORT_1(OS_ERROR,"u_partitionNew",0, "No Participant specified. " "For Partition: <%s>", name); } return _this; }
c_bool v_partitionAdminSet( v_partitionAdmin da, v_partitionPolicy partitionExpr, c_iter *addedPartitions, c_iter *removedPartitions) { c_iter dexpressions; /* iterator of partition expressions */ c_char *dexpr; /* partition expression */ v_partitionInterest di; struct resolvePartitionsArg resolveArg; struct updatePartitionsArg updateArg; assert(C_TYPECHECK(da, v_partitionAdmin)); assert(removedPartitions != NULL); assert(addedPartitions != NULL); *removedPartitions = NULL; *addedPartitions = NULL; resolveArg.kernel = v_objectKernel(da); c_mutexLock(&da->mutex); /* * The absolute partition names will be added at the end of * the algorithm. * The partition expressions in the parameter of partitionExpr, * replace the existing in da->partitionInterests. */ c_free(da->partitionInterests); da->partitionInterests = c_tableNew(v_kernelType(resolveArg.kernel, K_DOMAININTEREST), "expression"); assert(c_count(da->partitionInterests) == 0); dexpressions = v_partitionPolicySplit(partitionExpr); if (dexpressions == NULL) { /* switch to default */ *addedPartitions = c_iterInsert(*addedPartitions, v_partitionNew(resolveArg.kernel, "", NULL)); } else { dexpr = (c_char *)c_iterTakeFirst(dexpressions); while (dexpr != NULL) { if (v_partitionExpressionIsAbsolute(dexpr)) { *addedPartitions = c_iterInsert(*addedPartitions, v_partitionNew(resolveArg.kernel, dexpr, NULL)); /* ref transferred to addedPartitions */ } else { di = v_partitionInterestNew(resolveArg.kernel, (const c_char *)dexpr); c_tableInsert(da->partitionInterests, di); c_free(di); } os_free(dexpr); dexpr = (c_char *)c_iterTakeFirst(dexpressions); } c_iterFree(dexpressions); } /* * The given expressions are now divided across * 'addedpartitions' and 'da->partitionInterests'. * Now first add partitions to 'addedpartitions' that fit the * expressions in 'da->partitionInterests'. */ resolveArg.partitions = addedPartitions; c_tableWalk(da->partitionInterests, resolvePartitions, (c_voidp)&resolveArg); /* * Now 'addedpartitions' contains all partitions to be added * by the publisher/subscriber. * 'da->partitions' contains the old set of partitions. * We must check whether those partitions must remain in * the set or must be removed. * For every partition in 'da->partitions' do * if partition in 'addedpartitions' then remove from 'addedpartitions' * else add to 'removedpartitions' * For every partition in 'removedpartitions' remove from 'da->partitions'. */ updateArg.addPartitions = addedPartitions; updateArg.removePartitions = removedPartitions; c_tableWalk(da->partitions, updatePartitions, (c_voidp)&updateArg); c_iterWalk(*removedPartitions, removePartition, (c_voidp)da->partitions); /* * The da->partitions now contains partitions that still comply to new * partitionPolicy. So all partitions in added partitions, must be added * to da->partitions, so it reflects all connected partitions. */ c_iterWalk(*addedPartitions, addPartition, (c_voidp)da->partitions); c_mutexUnlock(&da->mutex); return TRUE; }
u_group u_groupNew( u_participant participant, const c_char *partitionName, const c_char *topicName, v_duration timeout) { u_result r; v_participant kparticipant; v_kernel kernel; v_topic ktopic; v_partition kpartition; v_group kgroup; c_iter topics; os_time delay; u_group group = NULL; if ((partitionName != NULL) && (topicName != NULL)) { if (participant != NULL) { r = u_entityWriteClaim(u_entity(participant), (v_entity*)(&kparticipant)); if (r == U_RESULT_OK){ assert(kparticipant); kernel = v_objectKernel(kparticipant); topics = v_resolveTopics(kernel,topicName); if (c_iterLength(topics) == 0) { c_iterFree(topics); delay.tv_sec = timeout.seconds; delay.tv_nsec = timeout.nanoseconds; os_nanoSleep(delay); topics = v_resolveTopics(v_objectKernel(kparticipant), topicName); } if (c_iterLength(topics) > 1) { OS_REPORT_1(OS_WARNING, "u_groupNew", 0, "Internal error: " "Multiple topics found with name = <%s>.", topicName); } ktopic = c_iterTakeFirst(topics); /* If ktopic == NULL, the topic definition is unknown. * This is not critical since it may become known in the near future. * In that case the caller is responsible for retrying to create this group, * and log something if, eventually, the group still cannot be created. */ if (ktopic != NULL) { kpartition = v_partitionNew(kernel, partitionName, NULL); if (kpartition != NULL) { kgroup = v_groupSetCreate(kernel->groupSet, kpartition, ktopic); if (kgroup != NULL) { group = u_groupCreate(kgroup, participant); if (group == NULL) { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Create proxy failed. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } c_free(kgroup); } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Create kernel entity failed. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } c_free(kpartition); } else { OS_REPORT_2(OS_ERROR,"u_groupNew", 0, "Failed to create partition. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } c_free(ktopic); } ktopic = c_iterTakeFirst(topics); while (ktopic != NULL) { c_free(ktopic); ktopic = c_iterTakeFirst(topics); } c_iterFree(topics); r = u_entityRelease(u_entity(participant)); } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Claim kernel participant failed." "For Partition <%s> and Topic <%s>.", partitionName, topicName); } } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "No participant specified. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Illegal parameter." "partitionName = <0x%x>, topicName = <0x%x>.", partitionName, topicName); } return group; }
u_group u_groupNew( u_participant participant, const c_char *partitionName, const c_char *topicName, v_duration timeout) { u_result r; v_participant kparticipant; v_kernel kernel; v_topic ktopic; v_partition kpartition; v_group kgroup; c_iter topics; os_time delay; u_group group = NULL; if ((partitionName != NULL) && (topicName != NULL)) { if (participant != NULL) { r = u_entityWriteClaim(u_entity(participant), (v_entity*)(&kparticipant)); if (r == U_RESULT_OK){ assert(kparticipant); kernel = v_objectKernel(kparticipant); topics = v_resolveTopics(kernel,topicName); if (c_iterLength(topics) == 0) { c_iterFree(topics); delay.tv_sec = timeout.seconds; delay.tv_nsec = timeout.nanoseconds; os_nanoSleep(delay); topics = v_resolveTopics(v_objectKernel(kparticipant), topicName); } if (c_iterLength(topics) > 1) { OS_REPORT_1(OS_WARNING, "u_groupNew", 0, "Internal error: " "Multiple topics found with name = <%s>.", topicName); } ktopic = c_iterTakeFirst(topics); if (ktopic != NULL) { kpartition = v_partitionNew(kernel, partitionName, NULL); if (kpartition != NULL) { kgroup = v_groupSetCreate(kernel->groupSet, kpartition, ktopic); if (kgroup != NULL) { group = u_groupCreate(kgroup, participant); if (group == NULL) { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Create proxy failed. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } c_free(kgroup); } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Create kernel entity failed. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } c_free(kpartition); } else { OS_REPORT_2(OS_ERROR,"u_groupNew", 0, "Failed to create partition. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } c_free(ktopic); }else { OS_REPORT_2(OS_ERROR,"u_groupNew", 0, "Topic not (yet) known. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } ktopic = c_iterTakeFirst(topics); while (ktopic != NULL) { c_free(ktopic); ktopic = c_iterTakeFirst(topics); } c_iterFree(topics); r = u_entityRelease(u_entity(participant)); } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Claim kernel participant failed." "For Partition <%s> and Topic <%s>.", partitionName, topicName); } } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "No participant specified. " "For Partition <%s> and Topic <%s>.", partitionName, topicName); } } else { OS_REPORT_2(OS_ERROR,"u_groupNew",0, "Illegal parameter." "partitionName = <0x%x>, topicName = <0x%x>.", partitionName, topicName); } return group; }