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; }
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; }