Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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;
}