Пример #1
0
/**************************************************************
 * constructor/destructor
 **************************************************************/
v_service
v_serviceNew(
    v_serviceManager manager,
    const c_char *name,
    const c_char *extStateName,
    v_participantQos qos,
    v_statistics stats)
{
    v_kernel k;
    v_service s;
    v_participantQos q;

    assert(C_TYPECHECK(manager, v_serviceManager));
    /* Do not C_TYPECHECK qos parameter, since it might be allocated on heap! */
    assert(name != NULL);

    k = v_objectKernel(manager);
    /* do no use cast method on qos parameter,
     * it is most likely allocated on heap! */
    q = v_participantQosNew(k, (v_participantQos)qos);
    if (q == NULL) {
        OS_REPORT(OS_ERROR, "v_serviceNew", 0,
                  "Service not created: inconsistent qos");
        s = NULL;
    } else {
        s = v_service(v_objectNew(k, K_SERVICE));
        v_serviceInit(s, manager, name, extStateName, q, stats);
        c_free(q);
        /* always add, even when s->state==NULL, since v_participantFree always
           removes the participant.*/
        v_addParticipant(k, v_participant(s));
        if (s->state == NULL) {
            v_serviceFree(s);
            s = NULL;
        }
    }

    return s;
}
Пример #2
0
void
v_cfElementInit (
    v_cfElement element,
    v_configuration config,
    const c_char *tagName)
{
    c_type attrType;
    c_type nodeType;
    const c_char *keyList;
    
    assert(C_TYPECHECK(element, v_cfElement));
    assert(tagName != NULL);

    v_cfNodeInit(v_cfNode(element), config, V_CFELEMENT, tagName);

    attrType = c_resolve(c_getBase(element), "kernelModule::v_cfAttribute");
    nodeType = c_resolve(c_getBase(element), "kernelModule::v_cfNode");
    keyList = "name";

    element->attributes = c_tableNew(attrType, keyList);
    element->children = c_setNew(nodeType);
}
Пример #3
0
/* Precondition: protect the sample yourself */
v_writerSampleStatus
_v_writerSampleGetStatus(
    v_writerSample sample)
{
    v_writerSampleStatus result;

    assert(sample);
    assert(C_TYPECHECK(sample,v_writerSample));

    if ((c_long)sample->resend == TRUE) {
        /* Someone has rejected the sample, resend it */
        result = V_SAMPLE_RESEND;
    } else {
        if ((c_long)sample->decayCount > 0) {
            result = V_SAMPLE_KEEP;
        } else {
            result = V_SAMPLE_RELEASE;
        }
    }

    return result;
}
Пример #4
0
void
v_listenerFlush(
    v_listener _this,
    v_eventMask events,
    c_voidp userData)
{
    v_listenerEvent event, *prev;

    if (_this == NULL) {
        return;
    }
    assert(C_TYPECHECK(_this,v_listener));
    c_mutexLock(&_this->mutex);
    /* wakeup blocking threads to evaluate new condition. */
    /* remove all events */
    prev = &_this->eventList;
    event = _this->eventList;
    while (event != NULL) {
        if (event->userData == userData) {
            event->kind &= ~events;
        }
        if (event->kind == 0) {
            if (event == _this->lastEvent) {
                _this->lastEvent = c_keep(_this->lastEvent->next);
                v_listenerEventDeinit(event);
                c_free(event);
            }
            *prev = event->next;
            v_listenerEventDeinit(event);
            c_free(event);
            event = *prev;
        } else {
            prev = &event->next;
            event = event->next;
        }
    }
    c_condBroadcast(&_this->cv);
    c_mutexUnlock(&_this->mutex);
}
Пример #5
0
/**************************************************************
 * constructor/destructor
 **************************************************************/
v_leaseManager
v_leaseManagerNew(
    v_kernel k)
{
    v_leaseManager _this;

    assert(C_TYPECHECK(k, v_kernel));

    _this = v_leaseManager(v_objectNew(k, K_LEASEMANAGER));
    if(_this)
    {
        v_leaseManagerInit(_this);
    } else
    {
        OS_REPORT(OS_ERROR, "v_leaseManager", 0,
            "Failed to create a v_leaseManager object. "
            "Most likely not enough shared memory available "
            "to complete the operation.");
    }

    return _this;
}
Пример #6
0
/**
 * This method will invalidate a handle and mark the resources as ready for reuse.
 * Note that the info and handle musr correspond and that info is locked.
 */
static void
v_handleInvalidate (
    v_handle handle,
    v_handleInfo *info)
{
    v_handleServer server;
    c_object entity;

    server = v_handleServer((c_object)handle.server);
    assert(C_TYPECHECK(server,v_handleServer));
    if (server) {
        c_mutexLock(&server->mutex);
        info->nextFree = server->firstFree;
        server->firstFree = handle.index;
        info->serial = (info->serial + 1) % MAXSERIAL;
        entity = info->object;
        info->object = NULL;
        c_mutexUnlock(&server->mutex);
        c_mutexUnlock(&info->mutex);
        v_publicDispose(v_public(entity));
    }
}
Пример #7
0
v_writeResult
v_instanceWrite(
    v_instance instance,
    v_message message)
{
    c_char *metaName;

    assert(C_TYPECHECK(instance, v_instance));

    switch (v_objectKind(instance)) {
    case K_DATAREADERINSTANCE:
        return v_dataReaderInstanceWrite(v_dataReaderInstance(instance),message);
    default:
        metaName = c_metaName(c_metaObject(c_getType(instance)));
        OS_REPORT_1(OS_ERROR,
                    "v_instanceWrite",0,
                    "Unknown instance type <%s>",
                    metaName);
        c_free(metaName);
        return V_WRITE_PRE_NOT_MET;
    }
}
Пример #8
0
void
v_listenerFree(
   v_listener _this)
{
    v_participant p;
    v_listenerEvent event;
    os_duration delay;

    assert(_this != NULL);
    assert(C_TYPECHECK(_this,v_listener));
    p = v_participant(_this->participant);
    assert(p != NULL);

    c_mutexLock(&_this->mutex);

    /* wakeup blocking threads to evaluate new condition. */
    /* remove all events */
    while (_this->eventList != NULL) {
        event = _this->eventList;
        _this->eventList = event->next;
        v_listenerEventDeinit(event);
        c_free(event);
    }
    _this->eventList = NULL;
    c_free(_this->lastEvent);
    _this->lastEvent = NULL;
    _this->terminate = TRUE;
    c_condBroadcast(&_this->cv);
    c_mutexUnlock(&_this->mutex);

    delay = OS_DURATION_INIT(0, 1000);
    while (_this->waitCount > 0 && !p->processIsZombie) {
        ospl_os_sleep(delay);
    }

    v_participantRemove(p, v_object(_this));
    _this->participant = NULL;
    v_publicFree(v_public(_this));
}
Пример #9
0
v_topicAdapter
v_topicAdapterNewFromTopicInfo(
    v_participant p,
    const struct v_topicInfo *info,
    c_bool announce)
{
    v_topicAdapter adapter = NULL;
    v_topicImpl topic;
    v_kernel kernel;

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

    kernel = v_objectKernel(p);

    topic = v_topicImplNewFromTopicInfo(kernel, info, announce);
    if (topic) {
        adapter = v_topicAdapterWrap(p, v_topic(topic));
    }

    return adapter;
}
Пример #10
0
v_writeResult
v_networkReaderEntryWrite(
    v_networkReaderEntry entry,
    v_message message,
    v_networkId writingNetworkId)
{
    v_writeResult result = V_WRITE_SUCCESS;
    c_bool writeSucceeded;
    static v_gid zeroAddressee = {0,0,0};

    assert(C_TYPECHECK(entry, v_networkReaderEntry));
    assert(message != NULL);

    /* First check if there is any remote interest at all */

    if (v_networkReader(v_entry(entry)->reader)->remoteActivity) {
        /* Only forward messages that come from this kernel */
        if (writingNetworkId == V_NETWORKID_LOCAL || entry->isRouting) {
            /* OK, message is from this kernel or this is a routing entry. Now
             * attach the correct fields if needed */

            /* TODO: For networking services that support routing perhaps
             * messages shouldn't be forwarded to 'self' (e.g., echo cancellation
             * may be needed). For R&R this modus is fine. */
            writeSucceeded = v_networkReaderWrite(
                                  v_networkReader(v_entry(entry)->reader),
                                  message, entry, 0, message->writerGID,
                                  FALSE /* no p2p */, zeroAddressee);
            if (writeSucceeded) {
                result = V_WRITE_SUCCESS;
            } else {
                result = V_WRITE_REJECTED;
            }
        }
    }

    return result;
}
Пример #11
0
/**************************************************************
 * constructor/destructor
 **************************************************************/
v_cfNode
v_cfNodeNew(
    v_configuration config,
    v_cfKind kind)
{
    v_cfNode node;
    c_type type;
    
    assert(C_TYPECHECK(config, v_configuration));
    
    switch (kind) {
    case V_CFELEMENT:
        type = c_resolve(c_getBase(config), "kernelModule::v_cfElement");
    break;
    case V_CFATTRIBUTE:
        type = c_resolve(c_getBase(config), "kernelModule::v_cfAttribute");
    break;
    case V_CFDATA:
        type = c_resolve(c_getBase(config), "kernelModule::v_cfData");
    break;
    case V_CFNODE:
    default:
        OS_REPORT_1(OS_ERROR,"v_cfNodeNew failed",0,"Illegal kind (%d) specified",kind);
        assert(FALSE); 
        type = NULL;
    break;
    }

    if (type != NULL) {
        node = c_new(type);
    } else {
        node = NULL;
    }
    /* init is done by specific class itself, this is just a 
       convenience function! */

    return node;
}
Пример #12
0
v_result
v_deliveryWaitListNotify (
    v_deliveryWaitList _this,
    v_deliveryInfoTemplate msg)
{
    c_ulong size, i, count;
    v_gid *list;

    assert(C_TYPECHECK(_this,v_deliveryWaitList));
    assert(msg);

    list = (v_gid *)_this->readerGID;
    if(msg->userData.sequenceNumber == _this->sequenceNumber)
    {
        count = 0;
        
        size = c_arraySize(_this->readerGID);
        for (i=0; i<size; i++) {
            if (v_gidEqual(list[i],msg->userData.readerGID)) {
                /* Set the found readerGID to zero,
                 * iThe waitlist can be unblocked when
                 * all expected systemIds are zero.
                 * In that case count will be 0.
                 */
                v_gidSetNil(list[i]);
            }
            count += v_gidSystemId(list[i]);
        }
        if (count == 0) {
            c_free(_this->readerGID);
            _this->readerGID = NULL;
            c_mutexLock(&_this->mutex);
            c_condSignal(&_this->cv);
            c_mutexUnlock(&_this->mutex);
        }
    }
    return V_RESULT_OK;
}
Пример #13
0
c_iter
v_resolveTopics(
    v_kernel kernel,
    const c_char *name)
{
    c_iter list;
    c_collection q;
    q_expr expr;
    c_value params[1];

    assert(kernel != NULL);
    assert(C_TYPECHECK(kernel,v_kernel));

    expr = (q_expr)q_parse("name like %0");
    params[0] = c_stringValue((char *)name);
    q = c_queryNew(kernel->topics,expr,params);
    q_dispose(expr);
    c_lockRead(&kernel->lock);
    list = c_select(q,0);
    c_lockUnlock(&kernel->lock);
    c_free(q);
    return list;
}
Пример #14
0
void
v_dataViewInstanceRemove(
    v_dataViewInstance instance)
{
    v_dataView dataView;
    v_dataViewInstance found;

    assert(C_TYPECHECK(instance,v_dataViewInstance));

    if (instance->sampleCount == 0) {
        CHECK_ZERO_INSTANCE(instance);
        if (v_objectKind (instance) == K_DATAVIEWINSTANCE) {
            dataView = v_dataView(v_instanceEntity(instance));
            found = c_remove(dataView->instances,instance,NULL,NULL);
            assert(found == instance);
            OS_UNUSED_ARG(found);
            v_publicFree(v_public(instance));
            c_free(instance);
        }
    } else {
        CHECK_INSTANCE(instance);
    }
}
Пример #15
0
void
writerDeadlineMissed(
    v_leaseAction leaseAction,
    c_time now)
{
    v_object w;
    v_handleResult r;

    assert(leaseAction != NULL);
    assert(C_TYPECHECK(leaseAction, v_leaseAction));

    r = v_handleClaim(leaseAction->actionObject, &w);
    if (r == V_HANDLE_OK)
    {
        v_writerCheckDeadlineMissed(v_writer(w), now);
        r = v_handleRelease(leaseAction->actionObject);
        if(r != V_HANDLE_OK)
        {
            OS_REPORT_1(OS_WARNING, "v_leaseManager", 0,
                "Handle release failed with result code %d ", r);
        }
    }
}
Пример #16
0
c_ulong
v__observerWait(
    v_observer o)
{
    os_result result = os_resultSuccess;
    c_ulong flags;

    assert(o != NULL);
    assert(C_TYPECHECK(o,v_observer));

    if (o->eventFlags == 0) {
        o->waitCount++;
        result = c_condWait(&o->cv,&o->mutex);
        o->waitCount--;
    }
    flags = o->eventFlags;
    /* Reset events but remember destruction event.
     * To avoid any further use of this observer in case of destruction.
     */
    o->eventFlags &= V_EVENT_OBJECT_DESTROYED;

    return flags;
}
Пример #17
0
void
v_groupStreamDeinit(
    v_groupStream stream)
{
    c_iter groups;
    v_group group;

    assert(C_TYPECHECK(stream, v_groupStream));

    v_readerDeinit(v_reader(stream));

    groups = ospl_c_select(stream->groups, 0);
    group = v_group(c_iterTakeFirst(groups));

    while(group){
        v_groupRemoveStream(group, stream);
        c_free(group);
        group = v_group(c_iterTakeFirst(groups));
    }
    c_iterFree(groups);
    c_free(stream->groups);
    stream->groups = NULL;
}
Пример #18
0
/**************************************************************
 * Protected functions
 **************************************************************/
v_partitionAdmin
v_partitionAdminNew(
    v_kernel kernel)
{
    v_partitionAdmin da;
    c_base base;

    assert(C_TYPECHECK(kernel,v_kernel));

    base = c_getBase(kernel);
    da = v_partitionAdmin(v_objectNew(kernel, K_DOMAINADMIN));
    if (da != NULL) {
        da->partitions         = c_tableNew(v_kernelType(kernel, K_DOMAIN),"name");
        da->partitionInterests = c_tableNew(v_kernelType(kernel, K_DOMAININTEREST), "expression");
        c_mutexInit(&da->mutex,SHARED_MUTEX);

        if ((da->partitions == NULL) || (da->partitionInterests == NULL)) {
            c_free(da);
            da = NULL;
        }
    }
    return da;
}
Пример #19
0
v_result
v_deliveryWaitListFree(
    v_deliveryWaitList _this)
{
    v_deliveryWaitList found;
    v_result result;

    assert(C_TYPECHECK(_this,v_deliveryWaitList));

    if (_this) {
        /* lookup or create a writer specific admin.
         */
        found = c_remove(v_deliveryGuard(_this->guard)->waitlists, _this, NULL, NULL);
        assert(found == _this);
        assert(c_refCount(found) == 2);
        c_free(found);
        c_free(_this);
        result = V_RESULT_OK;
    } else {
        result = V_RESULT_ILL_PARAM;
    }
    return result;
}
Пример #20
0
v_rnr
v_rnrNew(
    v_kernel kernel,
    const c_char *name,
    const c_char *extStateName,
    v_participantQos qos,
    c_bool enable)
{
    v_rnr _this;
    v_participantQos q;

    assert(C_TYPECHECK(kernel, v_kernel));
    assert(name != NULL);

    q = v_participantQosNew(kernel, qos);
    if (q == NULL) {
        OS_REPORT(OS_ERROR, "v_rnrNew", V_RESULT_ILL_PARAM,
                  "Record and Replay service not created: inconsistent qos");
        _this = NULL;
    } else {
        _this = v_rnr(v_objectNew(kernel, K_RNR));
        _this->statistics = v_rnrStatisticsNew (kernel, name);
        v_serviceInit(v_service(_this), name, extStateName, V_SERVICETYPE_RECORD_REPLAY, q, enable);
        c_free(q);
        /* always add, even when s->state==NULL, since v_participantFree always
         * removes the participant.
         */
        v_addParticipant(kernel, v_participant(_this));
        if (v_service(_this)->state == NULL) {
            v_serviceFree(v_service(_this));
            _this = NULL;
        } else {
            OSPL_ADD_OBSERVER(kernel, _this, V_EVENT_NEW_GROUP, NULL);
        }
    }
    return _this;
}
Пример #21
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));

    /* First select the best queue */
    if (reader->remoteActivity && !(pa_ld32(&v_objectKernel(reader)->isolate) & V_ISOLATE_MUTE)) {
        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);
    } else {
        result = TRUE;
    }

    return result;
}
Пример #22
0
v_waitset
v_waitsetNew(
    v_participant p)
{
    v_waitset _this;
    v_kernel kernel;
    c_type proxyType;

    assert(C_TYPECHECK(p,v_participant));

    kernel = v_objectKernel(p);
    _this = v_waitset(v_objectNew(kernel,K_WAITSET));
    if (_this != NULL) {
        v_observerInit(v_observer(_this),"Waitset", NULL, TRUE);
        _this->participant = p;
        _this->eventCache = NULL;
        proxyType = v_kernelType(kernel,K_PROXY);
        _this->observables = c_setNew(proxyType);
        v_observerSetEventData(v_observer(_this), NULL);
        v_participantAdd(p, v_entity(_this));
    }

    return _this;
}
Пример #23
0
void
livelinessCheck(
    v_leaseManager _this,
    v_leaseAction leaseAction)
{
    v_object o;
    v_handleResult r;

    assert(leaseAction != NULL);
    assert(C_TYPECHECK(leaseAction, v_leaseAction));

    /* Liveliness lease expired, so the reader/writer must be notified! */
    r = v_handleClaim(leaseAction->actionObject, &o);
    if (r == V_HANDLE_OK)
    {
        v_writerNotifyLivelinessLost(v_writer(o));
        if (v_objectKind(o) != K_WRITER)
        {
            OS_REPORT_1(OS_WARNING, "v_lease", 0,
                        "entity %d has no liveliness policy",
                        v_objectKind(o));
        }
        r = v_handleRelease(leaseAction->actionObject);
        if(r != V_HANDLE_OK)
        {
            OS_REPORT_1(OS_WARNING, "v_leaseManager", 0,
                "Handle release failed with result code %d ", r);
        }
    } else
    {
        /* Corresponding reader/writer is already gone, so remove this lease
         * from its leasemanager.
         */
        v_leaseManagerDeregister(_this, leaseAction->lease);
    }
}
Пример #24
0
v_topicAdapter
v_topicAdapterNew(
    v_participant p,
    const c_char *name,
    const c_char *typeName,
    const c_char *keyExpr,
    v_topicQos qos)
{
    v_topicAdapter adapter = NULL;
    v_topicImpl topic;
    v_kernel kernel;

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

    kernel = v_objectKernel(p);

    topic = v_topicImplNew(kernel, name, typeName, keyExpr, qos, TRUE);
    if (topic) {
        adapter = v_topicAdapterWrap(p, v_topic(topic));
    }

    return adapter;
}
Пример #25
0
static d_instance
d_groupInfoLookupInstance (
    d_groupInfo _this,
    const v_groupAction action)
{
    c_long i, nrOfKeys;
    c_value keyValues[32];
    d_instance instance;
    c_array messageKeyList;

    assert(C_TYPECHECK(action->message,v_message));

    messageKeyList = v_topicMessageKeyList(action->group->topic);
    nrOfKeys = c_arraySize(messageKeyList);

    if (nrOfKeys > 32) {
        OS_REPORT_1(OS_ERROR,
                    "d_groupInfoGetInstance",0,
                    "too many keys %d exceeds limit of 32",
                    nrOfKeys);
        instance = NULL;
    } else {
        for (i=0;i<nrOfKeys;i++) {
            keyValues[i] = c_fieldValue(messageKeyList[i],action->message);
        }
        instance = c_tableFind(_this->instances, &keyValues[0]);
        c_keep(instance);



        for (i=0;i<nrOfKeys;i++) {
            c_valueFreeRef(keyValues[i]);
        }
    }
    return instance;
}
Пример #26
0
void
v_cfAttributeInit (
    v_cfAttribute attribute,
    v_configuration config,
    const c_char *name,
    c_value value)
{
    assert(C_TYPECHECK(attribute, v_cfAttribute));
    assert(name != NULL);

    v_cfNodeInit(v_cfNode(attribute), config, V_CFATTRIBUTE, name);

    attribute->value = value;
    switch (value.kind) {
    case V_STRING:
        attribute->value.is.String = c_stringNew(c_getBase(c_object(config)),
                                                 value.is.String);
    break;
    case V_UNDEFINED:
    case V_BOOLEAN: case V_OCTET:
    case V_SHORT:   case V_LONG:   case V_LONGLONG:
    case V_USHORT:  case V_ULONG:  case V_ULONGLONG:
    case V_FLOAT:   case V_DOUBLE:
    case V_CHAR:    
    case V_WCHAR:   case V_WSTRING:
    case V_FIXED:   case V_OBJECT:
    default:
        /* nothing to copy */
        OS_REPORT_1(OS_ERROR,
                    "kernel", 0,
                    "Unknown value (%d) type given at creation of "
                    "configuration attribute.",
                     value.kind);
    break;
    }
}
Пример #27
0
v_networkReaderWaitResult
v_networkReaderWait(
    v_networkReader reader,
    c_ulong queueId,
    v_networkQueue *queue)
{
    v_networkReaderWaitResult result = V_WAITRESULT_NONE;
    assert(reader != NULL);
    assert(C_TYPECHECK(reader, v_networkReader));
    assert(queueId <= reader->nofQueues);
    assert(queue != NULL);

    *queue = NULL;
    if (queueId > 0) {
        result = v_networkQueueWait(reader->queues[queueId-1]);
        if (result & V_WAITRESULT_MSGWAITING) {
            *queue = reader->queues[queueId-1];
        }
    } else {
        result = V_WAITRESULT_FAIL;
    }

    return result;
}
Пример #28
0
void
v_groupStreamConnectNewGroups(
    v_groupStream stream,
    v_group group)
{
    struct groupConnected data;

    assert(stream != NULL);
    assert(C_TYPECHECK(stream,v_groupStream));
    v_observerLock(v_observer(stream));

    /*
     * 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     = group;

    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, group);
    }
    v_observerUnlock(v_observer(stream));

    if(data.connected == FALSE){
        v_groupStreamHistoricalData(group, stream);
    }

    return;
}
Пример #29
0
c_bool
v_dataViewInstanceTakeSamples(
    v_dataViewInstance instance,
    c_query query,
    v_state sampleMask,
    v_readerSampleAction action,
    c_voidp arg)
{
    c_bool proceed;
    struct v_instanceQueryArg_s instanceQueryArg_s;

    assert(C_TYPECHECK(instance,v_dataViewInstance));

    if (query != NULL) {
        instanceQueryArg_s.query = query;
        instanceQueryArg_s.instance = instance;
        proceed = v_dataViewInstanceTakeWithCondition(
            instance, evalInstanceQuery, &instanceQueryArg_s, sampleMask, action, arg);
    } else {
        proceed = v_dataViewInstanceTakeWithCondition(instance,NULL,NULL,sampleMask,action,arg);
    }

    return proceed;
}
Пример #30
0
v_rnrGroupStatistics
v_rnrStorageStatisticsGroup(
        v_rnrStorageStatistics _this,
        v_service service,
        const c_char* name)
{
    v_kernel kernel;
    struct checkGroupExistsHelper helper;

    assert(_this);
    assert(C_TYPECHECK(_this, v_rnrStorageStatistics));
    assert(service && name);
    helper.name = name;
    helper.stats = NULL;

    if (c_walk(_this->topics, checkGroupExists, &helper)) {
        kernel = v_objectKernel(service);
        helper.stats = v_rnrGroupStatisticsNew(kernel, name);
        assert(helper.stats);
        c_tableInsert(_this->topics, helper.stats);
    }

    return helper.stats;
}