Esempio n. 1
0
v_topicAdapter
v_topicAdapterWrap(
    v_participant p,
    v_topic topic)
{
    v_topicAdapter adapter = NULL;
    v_kernel kernel;

    assert(p != NULL);
    assert(C_TYPECHECK(p,v_participant));
    assert(topic != NULL);
    assert(C_TYPECHECK(topic,v_topic));

    kernel = v_objectKernel(p);

    adapter = v_topicAdapter(v_objectNew(kernel,K_TOPIC_ADAPTER));
    if (adapter != NULL) {
        v_topicAdapterInit(adapter, topic, p, v_topicName(topic));
    } else {
        OS_REPORT(OS_ERROR, "v_topicAdapterWrap", V_RESULT_INTERNAL_ERROR,
                  "Failed to allocate TopicAdapter for topic '%s'.",
                   v_topicName(topic));
    }

    return adapter;
}
Esempio n. 2
0
c_bool
v_networkReaderWrite(
    v_networkReader reader,
    v_message message,
    v_networkReaderEntry entry,
    c_ulong sequenceNumber,
    v_gid sender,
    c_bool sendTo, /* for p2p writing */
    v_gid receiver)
{
    c_bool result;
    v_networkQueue bestQueue;

    assert(reader != NULL);
    assert(C_TYPECHECK(reader, v_networkReader));

    assert(reader->remoteActivity == TRUE);

    /* First select the best queue */
    if (message != NULL) {
        bestQueue = v_networkReaderSelectBestQueue(
                        reader,
                        message->qos,
                        sendTo,
                        v_partitionName(v_group(entry->group)->partition),
                        v_topicName(v_groupTopic(entry->group)));
    } else {
        bestQueue = reader->defaultQueue;
    }
    result = v_networkQueueWrite(bestQueue, message, entry,
                                 sequenceNumber, sender, sendTo, receiver);

    return result;
}
Esempio n. 3
0
static c_bool
walkProperty(
    c_metaObject object,
    c_metaWalkActionArg actionArg)
{
    toolActionData actionData = (toolActionData)actionArg;
    c_object o;
    c_voidp addr;

    o = c_iterObject(actionData->stack, 0);

    if (c_baseObjectKind(object) == M_ATTRIBUTE) {
        addr = C_DISPLACE(o, (c_address)c_property(object)->offset);
        if (c_typeIsRef(c_property(object)->type)) {
            addr = *(c_voidp *)addr;
            if (c_baseObjectKind(c_property(object)->type) == M_COLLECTION) {
                if (addr) {
                    if (c_iterContains(actionData->stack, addr)) {
                        printf("Ignore cyclic reference 0x"PA_ADDRFMT"\n",
                               (os_address)addr);
                    } else {
                        OBJECT_PUSH(actionData, addr);
                        iprintf("%s ",_METANAME(object));
                        printType(c_property(object)->type, actionData);
                        OBJECT_POP(actionData);
                    }
                } else {
                    iprintf("    %s <0x"PA_ADDRFMT">", _METANAME(object), (os_address)addr);
                }
            } else {
                iprintf("    %s <0x"PA_ADDRFMT">", _METANAME(object), (os_address)addr);
                if (addr) {
                    /* Section for code to print additional type specific info. */
                    if (c_property(object)->type == v_topic_t) {
                        printf(" /* topic name is: %s */", v_topicName(addr));
                    }
                    if (c_property(object)->type == v_partition_t) {
                        printf(" /* Partition: %s */", v_partitionName(addr));
                    }
                    if (c_property(object)->type == c_type_t(c_getBase(object))) {
                        printf(" /* Type: %s */", _METANAME(c_type(addr)));
                    }
                }
            }
            printf("\n");
        } else {
            OBJECT_PUSH(actionData, addr);
            iprintf("%s ",_METANAME(object));
            printType(c_property(object)->type, actionData);
            printf("\n");
            OBJECT_POP(actionData);
        }
    }
    return TRUE;
}
Esempio n. 4
0
static c_bool
isGroupConnected(
    v_group group,
    c_voidp args)
{
    struct groupConnected* data;

    assert(C_TYPECHECK(group, v_group));

    data = (struct groupConnected*)args;

    if(strcmp(v_partitionName(group->partition),
              v_partitionName(data->group->partition)) == 0){
        if(strcmp(v_topicName(group->topic),
                  v_topicName(data->group->topic)) == 0){
            data->connected = TRUE;
        }
    }
    return (!data->connected);
}
Esempio n. 5
0
static v_networkHashValue
v_networkReaderEntryCalculateHashValue(
    v_networkReaderEntry entry)
{
    v_networkHashValue result = {0xa0, 0x22, 0x8d, 0x07};

    const char *partitionName;
    const char *topicName;
    const char *currentPtr;

    partitionName = v_partitionName(v_groupPartition(entry->group));
    topicName = v_topicName(v_groupTopic(entry->group));
    currentPtr = partitionName;

    while (*currentPtr != '\0') {
        /* gcc2.96 gave internal compile errrors (with optimisation enabled)
         * when compiling the NW_ROT_CHAR macro twice in same command :
         * these assignments are deliberatly split over 2 lines as workaround.
         */

        result.h1 = NW_ROT_CHAR(result.h1, 1);
        result.h1 += NW_ROT_CHAR(*currentPtr, 4);

        result.h2 = NW_ROT_CHAR(result.h2, 2);
        result.h2 += NW_ROT_CHAR(*currentPtr, 7);

        result.h3 = NW_ROT_CHAR(result.h3, 3);
        result.h3 += NW_ROT_CHAR(*currentPtr, 1);

        result.h4 = NW_ROT_CHAR(result.h4, 4);
        result.h4 += NW_ROT_CHAR(*currentPtr, 5);

        currentPtr = &(currentPtr[1]);
    }

    currentPtr = topicName;
    while (*currentPtr != '\0') {
        result.h1 = NW_ROT_CHAR(result.h1, 4);
        result.h1 += NW_ROT_CHAR(*currentPtr, 7);

        result.h2 = NW_ROT_CHAR(result.h2, 3);
        result.h2 += NW_ROT_CHAR(*currentPtr, 1);

        result.h3 = NW_ROT_CHAR(result.h3, 2);
        result.h3 += NW_ROT_CHAR(*currentPtr, 5);

        result.h4 = NW_ROT_CHAR(result.h4, 1);
        result.h4 += NW_ROT_CHAR(*currentPtr, 4);

        currentPtr = &(currentPtr[1]);
    }
    return result;
}
Esempio n. 6
0
static c_bool
checkTopic (
    c_object o,
    c_voidp arg)
{
    v_dataReaderEntry entry;
    c_char *topicName = (c_char *)arg;

    if(v_object(o)->kind == K_DATAREADERENTRY){
        entry = v_dataReaderEntry(o);
        if (strcmp(v_topicName(entry->topic),topicName) == 0) {
            return FALSE;
        }
    }
    return TRUE;
}
Esempio n. 7
0
void
nw_receiveChannelAddGroup(
    nw_receiveChannel channel,
    v_networkReaderEntry entry)
{
    NW_CONFIDENCE(channel != NULL);

    if (channel != NULL) {
        /* Add entry to hashtable */
        nw_entryHashInsert(channel->hash, entry);
        NW_TRACE_3(Groups, 2,
                   "Channel %u added new group with partition %s and topic %s",
                   ((nw_channel)(channel))->channelId,
                   v_partitionName(v_groupPartition(entry->group)),
                   v_topicName(v_groupTopic(entry->group)));
    }
}
Esempio n. 8
0
static void
nw_entryHashInsert(
    nw_entryHash entryHash,
    v_networkReaderEntry entry)
{
    nw_entryHashItem *itemPtr;
    nw_bool ready = FALSE;
    int cmpRes;
    const c_char *partitionName;
    const c_char *topicName;

    partitionName = v_partitionName(v_groupPartition(entry->group));
    topicName = v_topicName(v_groupTopic(entry->group));
    itemPtr = &NW_ITEM_FROM_HASHVALUE(entryHash, entry->hashValue);
    while ((*itemPtr != NULL) && !ready) {
        cmpRes = strcmp((*itemPtr)->topicName, topicName);
        if (cmpRes == 0) {
            cmpRes = strcmp((*itemPtr)->partitionName, partitionName);
            if (cmpRes == 0) {
                ready = TRUE;
            } else if (cmpRes < 0) {
                itemPtr = &((*itemPtr)->next);
            } else {
                /* No entry was found and no entry will be found, insert new */
                nw_entryHashItemInsert(entry->hashValue, partitionName, topicName,
                                       entry, itemPtr);
                ready = TRUE;
            }
        } else if (cmpRes < 0) {
            itemPtr = &((*itemPtr)->next);
        } else {
            /* No entry found, and will not be found */
            nw_entryHashItemInsert(entry->hashValue, partitionName, topicName,
                                   entry, itemPtr);
            ready = TRUE;
        }
    }

    if (!ready) {
        /* No proper place found, we are at the tail now */
        nw_entryHashItemInsert(entry->hashValue, partitionName, topicName,
            entry, itemPtr);
    }
}
Esempio n. 9
0
c_ulong
nw_sendChannelWrite(
    nw_sendChannel sendChannel,
    v_networkReaderEntry entry,
    v_message message,
    nw_signedLength *maxBytes,
    plugSendStatistics pss)
{
    c_ulong result = 0;
    nw_channel channel = (nw_channel)sendChannel;

    NW_CONFIDENCE(channel);

    result = nw_bridgeWrite(channel->owningBridge, channel->channelId,
                            entry->networkPartitionId, message, entry->hashValue,
                            v_partitionName(v_groupPartition(entry->group)),
                            v_topicName(v_groupTopic(entry->group)),maxBytes, pss);

    return result;
}
Esempio n. 10
0
void
d_reportLocalGroup(
    d_durability d,
    const char *threadName,
    v_group group)
{
    const c_char* durability;
    v_topicQos qos;

    if(group){
        qos = v_topicQosRef(group->topic);
        switch(qos->durability.kind){
            case V_DURABILITY_VOLATILE:
                durability = "VOLATILE";
                break;
            case V_DURABILITY_TRANSIENT_LOCAL:
                durability = "TRANSIENT LOCAL";
                break;
            case V_DURABILITY_TRANSIENT:
                durability = "TRANSIENT";
                break;
            case V_DURABILITY_PERSISTENT:
                durability = "PERSISTENT";
                break;
            default:
                durability = "<<UNKNOWN>>";
                assert(FALSE);
                break;
        }
    } else {
        durability = "<<UNKNOWN>>";
        assert(FALSE);
    }
    d_printTimedEvent(d, D_LEVEL_FINE,
                      threadName, "Group found: %s.%s (%s)\n",
                      v_partitionName(v_groupPartition(group)),
                      v_topicName(v_groupTopic(group)),
                      durability);
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
static c_type
sampleTypeNew(
    v_topic topic)
{
    c_metaObject o;
    c_type msgType,sampleType,foundType;
    c_base base;
    c_char *name;
    os_size_t length;
    int sres;

    assert(C_TYPECHECK(topic,v_topic));
    assert(topic);

    name = NULL;
    foundType = NULL;

    if (v_topicName(topic) == NULL) {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive topic name");
        return NULL;
    }

    base = c_getBase(topic);

    if (base == NULL) {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive base");
        return NULL;
    }

    msgType = c_keep(v_topicMessageType(topic));

    if (msgType == NULL) {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive topic message type");
        return NULL;
    }

    sampleType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
    if (sampleType) {
        c_class(sampleType)->extends = v_dataReaderSample_t(base);
        o = c_metaDeclare(c_metaObject(sampleType),"message",M_ATTRIBUTE);
        if (o) {
            c_property(o)->type = c_keep(msgType);
            c_metaObject(sampleType)->definedIn = c_keep(base);
            c_metaFinalize(c_metaObject(sampleType));

#define SAMPLE_FORMAT "v_indexSample<%s>"
#define SAMPLE_NAME   "v_indexSample<>"
            /* sizeof contains \0 */
            length = sizeof(SAMPLE_NAME) + strlen(v_topicName(topic));
            name = os_malloc(length);
            sres = snprintf(name,length,SAMPLE_FORMAT,v_topicName(topic));
            assert(sres >= 0 && (os_size_t) sres == (length-1));
            OS_UNUSED_ARG(sres);
#undef SAMPLE_FORMAT
#undef SAMPLE_NAME

            foundType = c_type(c_metaBind(c_metaObject(base),
                                          name,
                                          c_metaObject(sampleType)));
            c_free(o);
        } else {
            foundType = NULL;
        }
        c_free(sampleType);
    } else {
        OS_REPORT(OS_ERROR,
                  "v_index::sampleTypeNew failed",V_RESULT_ILL_PARAM,
                  "failed to retreive topic sample type");
    }
    os_free(name);
    c_free(msgType);

    return foundType;
}
Esempio n. 13
0
static c_type
createInstanceType (
    v_topic topic,
    c_char *keyExpr,
    c_array *keyListRef)
{
    c_metaObject o;
    c_type instanceType, baseType, foundType;
    c_type sampleType, keyType, keyInstanceType;
    c_base base;
    c_char *name;
    os_size_t length;
    int sres;

    assert(C_TYPECHECK(topic,v_topic));

    foundType = NULL;
    if (keyExpr) {
        keyType = v_topicKeyTypeCreate(topic,keyExpr,keyListRef);
    } else {
        keyExpr = v_topicKeyExpr(topic);
        keyType = v_topicKeyType(topic);
        *keyListRef = c_keep(v_topicMessageKeyList(topic));
    }
    sampleType = sampleTypeNew(topic);
    if (sampleType) {
        base = c_getBase(topic);
        baseType = v_dataReaderInstance_t(base);
        instanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
        if (instanceType != NULL) {
            c_class(instanceType)->extends = c_keep(c_class(baseType));
            o = c_metaDeclare(c_metaObject(instanceType),
                              "sample",M_ATTRIBUTE);
            c_property(o)->type = c_keep(sampleType);
            c_free(o);
            o = c_metaDeclare(c_metaObject(instanceType),
                              "oldest",M_ATTRIBUTE);
            c_property(o)->type = (c_type)c_metaResolveType(c_metaObject(base),
                                                    "c_voidp");
            assert(c_property(o)->type);
            c_free(o);
            c_metaFinalize(c_metaObject(instanceType));
#define INSTANCE_NAME   "v_indexInstance<v_indexSample<>>"
#define INSTANCE_FORMAT "v_indexInstance<v_indexSample<%s>>"
            /* The sizeof contains \0 */
            length = sizeof(INSTANCE_NAME) + strlen(v_topicName(topic));
            name = os_alloca(length);
            sres = snprintf(name,length,INSTANCE_FORMAT,v_topicName(topic));
            assert(sres >= 0 && (os_size_t) sres == (length-1));
            OS_UNUSED_ARG(sres);
#undef INSTANCE_NAME
#undef INSTANCE_FORMAT
            foundType = c_type(c_metaBind(c_metaObject(base),
                                          name,
                                          c_metaObject(instanceType)));
            if (foundType == NULL) {
                OS_REPORT(OS_ERROR,
                        "v_index::createInstanceType",V_RESULT_INTERNAL_ERROR,
                        "Could not create instance type");
            }

            os_freea(name);

            if (keyType != NULL) {
                keyInstanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS));
                if (keyInstanceType) {
                    c_class(keyInstanceType)->extends = c_keep(c_class(instanceType));
                    o = c_metaDeclare(c_metaObject(keyInstanceType),
                                      "key",M_ATTRIBUTE);
                    c_property(o)->type = c_keep(keyType);
                    c_free(o);
                    c_metaFinalize(c_metaObject(keyInstanceType));
#define INSTANCE_NAME   "v_indexKeyInstance<v_indexSample<>,>"
#define INSTANCE_FORMAT "v_indexKeyInstance<v_indexSample<%s>,%s>"
                    /* The sizeof contains \0 */
                    length = sizeof(INSTANCE_NAME) +
                             strlen(v_topicName(topic)) +
                             strlen(keyExpr);
                    name = os_alloca(length);
                    sres = snprintf(name,
                                    length,
                                    INSTANCE_FORMAT,
                                    v_topicName(topic),
                                    keyExpr);
                    assert(sres >= 0 && (os_size_t) sres == (length-1));
                    OS_UNUSED_ARG(sres);
#undef INSTANCE_NAME
#undef INSTANCE_FORMAT
                    c_free(foundType); /* Will be overwritten, so free */
                    foundType = c_type(c_metaBind(c_metaObject(base),
                                                  name,
                                                  c_metaObject(keyInstanceType)));
                    if (foundType == NULL) {
                        OS_REPORT(OS_ERROR,
                                  "v_index::createInstanceType",V_RESULT_INTERNAL_ERROR,
                                  "Could not create key instance type");
                    }
                    os_freea(name);
                    c_free(keyInstanceType);
                }
                c_free(keyType);
            }
            c_free(instanceType);
            c_free(baseType);
        } else {
            foundType = baseType; /* transfer refCount to caller */
        }
        c_free(sampleType);
    }

    return foundType;
}