예제 #1
0
c_iter
v_serviceTakeNewGroups(
    v_service service)
{
    c_iter result;
    v_group group;
    c_set newGroups;

    assert(service != NULL);
    assert(C_TYPECHECK(service, v_service));

    result = c_iterNew(NULL);

    v_observerLock(v_observer(service));
    newGroups = (c_set)v_observer(service)->eventData;
    if (newGroups != NULL) {
        group = v_group(c_take(newGroups));
        while (group != NULL) {
            c_iterInsert(result, group);
            group = v_group(c_take(newGroups));
        }
    }
    v_observerUnlock(v_observer(service));

    return result;
}
예제 #2
0
u_result
u_dispatcherNotify(
    u_dispatcher _this)
{
    v_observer ko;
    u_result result = U_RESULT_OK;

    if (_this != NULL) {
         result = u_entityReadClaim(u_entity(_this), (v_entity*)(&ko));
        if (result == U_RESULT_OK) {
            assert(ko);
            /* Wakeup the dispatch thread */
            v_observerLock(ko);
            v_observerNotify(ko, NULL, NULL);
            v_observerUnlock(ko);
            result = u_entityRelease(u_entity(_this));
            if (result != U_RESULT_OK) {
                OS_REPORT(OS_ERROR, "u_dispatcherNotify", 0,
                          "Release observer failed.");
            }
        } else {
            OS_REPORT(OS_WARNING, "u_dispatcherNotify", 0,
                      "Failed to claim Dispatcher.");
        }
    } else {
        OS_REPORT(OS_ERROR,"u_dispatcherNotify",0,
                  "Illegal parameter.");
        result = U_RESULT_ILL_PARAM;
    }
    return result;
}
예제 #3
0
void
v_serviceRenewLease(
    v_service service,
    v_duration leasePeriod)
{
    assert(service != NULL);
    assert(C_TYPECHECK(service, v_service));

    v_observerLock(v_observer(service));
    v_leaseRenew(service->lease, &leasePeriod);
    v_observerUnlock(v_observer(service));
}
예제 #4
0
u_result
u_dispatcherDeinit(
    u_dispatcher _this)
{
    v_observer ko;
    u_listener listener;
    os_threadId tid;
    u_result result = U_RESULT_OK;

    if (_this != NULL) {
        os_mutexLock(&_this->mutex);
        listener = u_listener(c_iterTakeFirst(_this->listeners));
        while (listener != NULL) {
            u_listenerFree(listener);
            listener = u_listener(c_iterTakeFirst(_this->listeners));
        }
        c_iterFree(_this->listeners);
        _this->listeners = NULL; /* Flags the dispatch thread to stop */
        if (os_threadIdToInteger(_this->threadId) != 0U) {
            tid = _this->threadId;
            result = u_entityReadClaim(u_entity(_this), (v_entity*)(&ko));
            if(result != U_RESULT_OK) {
                /* This is a valid situation when a participant has been
                 * freed prior to the freeing of a dispatcher within the
                 * participant.
                 */
                os_mutexUnlock(&_this->mutex);
                os_threadWaitExit(tid, NULL);
                os_mutexDestroy(&_this->mutex);
                /*return U_RESULT_INTERNAL_ERROR;*/
            } else {
                /* Wakeup the dispatch thread */
                v_observerLock(ko);
                v_observerNotify(ko, NULL, NULL);
                v_observerUnlock(ko);
                u_entityRelease(u_entity(_this));
                os_mutexUnlock(&_this->mutex);
                os_threadWaitExit(tid, NULL);
                os_mutexDestroy(&_this->mutex);
            }
        } else {
            os_mutexUnlock(&_this->mutex);
            os_mutexDestroy(&_this->mutex);
        }
        result = u_entityDeinit(u_entity(_this));
    } else {
        OS_REPORT(OS_ERROR,"u_dispatcherDeinit",0,
                  "Illegal parameter.");
        result = U_RESULT_ILL_PARAM;
    }
    return result;
}
예제 #5
0
u_result
u_dispatcherRemoveListener(
    u_dispatcher _this,
    u_dispatcherListener listener)
{
    u_listener ul;
    v_observer ko;
    os_threadId tid;
    u_result result = U_RESULT_OK;
    struct compareArg arg;

    if ((_this != NULL) && (listener != NULL)) {
        os_mutexLock(&_this->mutex);
        arg.listener = listener;
        ul = (u_listener) c_iterResolve(_this->listeners, compare, &arg);
        tid = _this->threadId;
        if (ul != NULL) {
            c_iterTake(_this->listeners, ul);
            if (c_iterLength(_this->listeners) == 0) {
                result = u_entityReadClaim(u_entity(_this), (v_entity*)(&ko));
                if(result == U_RESULT_OK) {
                    assert(ko);
                    /* Wakeup the dispatch thread */
                    v_observerLock(ko);
                    v_observerNotify(ko, NULL, NULL);
                    v_observerUnlock(ko);
                    result = u_entityRelease(u_entity(_this));
                    if (result != U_RESULT_OK) {
                        OS_REPORT(OS_ERROR, "u_dispatcherRemoveListener", 0,
                                  "Release observer failed.");
                    }
                } else {
                    OS_REPORT(OS_WARNING, "u_dispatcherRemoveListener", 0,
                              "Failed to claim Dispatcher.");
                }
            }
            u_listenerFree(ul);
        }
        os_mutexUnlock(&_this->mutex);
        if ((c_iterLength(_this->listeners) == 0)
            && (os_threadIdToInteger(tid) != 0U)) {
            os_threadWaitExit(tid, NULL);
        }
    } else {
        OS_REPORT(OS_ERROR,"u_dispatcherInsertListener",0,
                  "Illegal parameter.");
        result = U_RESULT_ILL_PARAM;
    }
    return result;
}
예제 #6
0
void
v_serviceFillNewGroups(
    v_service service)
{
    c_set newGroups;
    C_STRUCT(v_event) ge;
    v_group g, oldGroup;
    c_iter oldGroups;
    v_kernel kernel;

    assert(service != NULL);
    assert(C_TYPECHECK(service, v_service));

    kernel = v_objectKernel(service);
    newGroups = (c_voidp)c_setNew(v_kernelType(kernel, K_GROUP));

    if (newGroups != NULL) {
        addAllGroups(newGroups, kernel->groupSet);
        v_observerLock(v_observer(service));
        g = v_group(c_read(newGroups)); /* need a group for the event */

        if(v_observer(service)->eventData != NULL){
            oldGroups = ospl_c_select((c_set)v_observer(service)->eventData, 0);
            oldGroup = v_group(c_iterTakeFirst(oldGroups));

            while(oldGroup){
                newGroups = c_setInsert(newGroups, oldGroup);
                c_free(oldGroup);
                oldGroup = v_group(c_iterTakeFirst(oldGroups));
            }
            c_iterFree(oldGroups);
        }
        /* just for safety, when assertion are compiled out, free the prev set */
        c_free((c_object)v_observer(service)->eventData);
        v_observer(service)->eventData = (c_voidp)newGroups;

        ge.kind = V_EVENT_NEW_GROUP;
        ge.source = v_publicHandle(v_public(kernel));
        ge.userData = g;
        v_observerNotify(v_observer(service), &ge, NULL);
        v_observerUnlock(v_observer(service));
        c_free(g);
    }
}
예제 #7
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;
}
예제 #8
0
void
cmx_readerSnapshotNewAction(
    v_entity e, 
    c_voidp args)
{
    v_dataReader reader;
    c_iter instances;
    v_dataReaderInstance instance;
    v_dataReaderSample sample, prev;
    v_query query;
    c_bool release;
    sd_serializer ser;
    sd_serializedData data;
    struct cmx_readerSnapshotArg* arg;
    
    release = FALSE;
    arg = (struct cmx_readerSnapshotArg*)args;
    reader = NULL;
    instances = NULL;
    ser = NULL;
    
    switch(v_object(e)->kind){
    case K_DATAREADER:
        reader = v_dataReader(e);
        arg->success = TRUE;
        arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot)));
        v_observerLock(v_observer(reader));
        
        if(reader->index->objects){
            instances = c_select(reader->index->notEmptyList, 0);
        }
    break;
    case K_QUERY:
    case K_DATAREADERQUERY:
        query = v_query(e);
        reader = v_dataReader(v_querySource(query));
        
        if(reader != NULL){
            release = TRUE;
            arg->success = TRUE;
            arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot)));
            v_observerLock(v_observer(reader));
            
            switch(v_object(query)->kind){
            case K_DATAREADERQUERY:
                if(v_dataReaderQuery(query)->instanceQ){
                    instances = c_select((c_collection)(v_dataReaderQuery(query)->instanceQ), 0);
                }
            break;
            default:
                OS_REPORT_1(OS_ERROR, CM_XML_CONTEXT, 0, 
                    "cmx_readerSnapshotNewAction unknown kind (%d).",
                    v_object(query)->kind);
            break;
            }
        }
    break;
    default:
    break;
    }
    if(arg->success == TRUE){
        arg->snapshot->samples = c_iterNew(NULL);
    }
    if(instances != NULL){
        instance = v_dataReaderInstance(c_iterTakeFirst(instances));
        
        while(instance != NULL){
            sample = c_keep(v_dataReaderInstanceHead(instance));
            
            if(sample != NULL){
                prev = sample->prev;
                sample->prev = NULL;
                
                if(ser == NULL){
                    ser = sd_serializerXMLNewTyped(c_getType(c_object(sample)));
                }
                data = sd_serializerSerialize(ser, c_object(sample));
                arg->snapshot->samples = c_iterInsert(arg->snapshot->samples, 
                                                sd_serializerToString(ser, data));
                sd_serializedDataFree(data);
                sample->prev = prev;
                c_free(sample);
            }
            c_free(instance);
            instance = v_dataReaderInstance(c_iterTakeFirst(instances));
        }
        c_iterFree(instances);
    }
    if(reader != NULL){
        v_observerUnlock(v_observer(reader));
        
        if(release == TRUE){
            c_free(reader);
        }
    }
    if(ser != NULL){
        sd_serializerFree(ser);
    }
}
예제 #9
0
void
cmx_readerDataTypeAction(
    v_entity entity,
    c_voidp args)
{
    sd_serializer ser;
    sd_serializedData data;
    c_type type;
    v_dataReader r;
    v_query query;
    v_topic topic;
    struct cmx_readerArg *arg;
    arg = (struct cmx_readerArg *)args;

    type = NULL;

    switch(v_object(entity)->kind){

    case K_DATAREADER:
        r = v_dataReader(entity);
        v_observerLock(v_observer(r));
        topic = v_dataReaderGetTopic(r);
        type = v_topicDataType(topic);
        c_free(topic);
        v_observerUnlock(v_observer(r));
    break;
    case K_DATAREADERQUERY:
        query = v_query(entity);
        r = v_dataReader(v_querySource(query));
        v_observerLock(v_observer(r));
        topic = v_dataReaderGetTopic(r);
        type = v_topicDataType(topic);
        c_free(topic);
        v_observerUnlock(v_observer(r));
        c_free(r);
    break;
    case K_NETWORKREADER:
        OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0,
                  "Resolving data type of networkReader unsupported.\n");
        assert(FALSE);
    break;
    case K_GROUPQUEUE:
        OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0,
                  "Resolving data type of groupQueue unsupported.\n");
        assert(FALSE);
    break;
    default:
        OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0,
                  "Trying to resolve dataType of unknown reader type.\n");
        assert(FALSE);
    break;
    }

    if(type != NULL){
        ser = sd_serializerXMLMetadataNew(c_getBase(type));
        data = sd_serializerSerialize(ser, type);
        arg->result = sd_serializerToString(ser, data);
        sd_serializedDataFree(data);
        sd_serializerFree(ser);
    }
}
예제 #10
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;
}
예제 #11
0
void
cmx_readerSnapshotNewAction(
    v_public p,
    c_voidp args)
{
    v_dataReader reader;
    c_iter instances;
    v_dataReaderInstance instance;
    v_dataReaderSample sample;
    v_query query;
    c_bool release;
    sd_serializer ser;
    sd_serializedData data;
    struct cmx_readerSnapshotArg* arg;

    release = FALSE;
    arg = (struct cmx_readerSnapshotArg*)args;
    reader = NULL;
    instances = NULL;
    ser = NULL;

    switch(v_object(p)->kind){
    case K_DATAREADER:
        reader = v_dataReader(p);
        arg->success = TRUE;
        arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot)));
        v_observerLock(v_observer(reader));

        if(reader->index->objects){
            instances = ospl_c_select(reader->index->notEmptyList, 0);
        }
    break;
    case K_QUERY:
    case K_DATAREADERQUERY:
        query = v_query(p);
        reader = v_dataReader(v_querySource(query));

        if(reader != NULL){
            release = TRUE;
            arg->success = TRUE;
            arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot)));
            v_observerLock(v_observer(reader));

            switch(v_object(query)->kind){
            case K_DATAREADERQUERY:
                if(v_dataReaderQuery(query)->instanceQ){
                    instances = ospl_c_select((c_collection)(v_dataReaderQuery(query)->instanceQ), 0);
                }
            break;
            default:
                OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0,
                    "cmx_readerSnapshotNewAction unknown kind (%d).",
                    v_object(query)->kind);
            break;
            }
        }
    break;
    default:
    break;
    }
    if(arg->success == TRUE){
        arg->snapshot->samples = c_iterNew(NULL);
    }
    if(instances != NULL){
        v_dataReaderSample sampleShallowCopy = NULL;
        instance = v_dataReaderInstance(c_iterTakeFirst(instances));

        while(instance != NULL){
            v_state ivState = instance->_parent._parent.state & (L_DISPOSED | L_NOWRITERS | L_NEW);

            sample = v_dataReaderInstanceOldest(instance);
            if (sample != NULL) {
                do {
                    v_state state = ivState | ((sample->_parent.sampleState & (L_READ | L_LAZYREAD)) ? L_READ : 0);

                    if (sampleShallowCopy == NULL) {
                        sampleShallowCopy = c_new(c_getType(c_object(sample)));
                    }
                    memcpy(sampleShallowCopy, sample, c_typeSize(c_getType(sampleShallowCopy)));
                    sampleShallowCopy->newer = NULL;
                    sampleShallowCopy->_parent.sampleState &= ~(L_DISPOSED | L_NOWRITERS | L_NEW | L_READ | L_LAZYREAD);
                    sampleShallowCopy->_parent.sampleState |= state;

                    if(ser == NULL){
                        ser = sd_serializerXMLNewTyped(c_getType(c_object(sampleShallowCopy)));
                    }
                    data = sd_serializerSerialize(ser, c_object(sampleShallowCopy));
                    arg->snapshot->samples = c_iterInsert(arg->snapshot->samples, sd_serializerToString(ser, data));
                    sd_serializedDataFree(data);

                    sample = sample->newer;
                } while (sample != NULL);
            }
            c_free(instance);
            instance = v_dataReaderInstance(c_iterTakeFirst(instances));
        }
        c_iterFree(instances);

        if (sampleShallowCopy != NULL) {
            memset(sampleShallowCopy, 0, c_typeSize(c_getType(sampleShallowCopy)));
            c_free(sampleShallowCopy);
        }
    }
    if(reader != NULL){
        v_observerUnlock(v_observer(reader));

        if(release == TRUE){
            c_free(reader);
        }
    }
    if(ser != NULL){
        sd_serializerFree(ser);
    }
}