コード例 #1
0
ファイル: d_waitset.c プロジェクト: xrl/opensplice_dds
static void*
d_waitsetEventHandler(
    void* userData)
{
    d_subscriber subscriber;
    d_durability durability;
    d_admin admin;
    c_iter events;
    d_waitsetEntity we;
    c_time time;
    d_waitsetHelper helper;
    u_waitset userWaitset;
    u_waitsetEvent event;
    u_result ur;

    helper           = d_waitsetHelper(userData);
    we               = helper->entity;
    subscriber       = d_waitsetGetSubscriber(helper->waitset);
    admin            = d_subscriberGetAdmin(subscriber);
    durability       = d_adminGetDurability(admin);
    time.seconds     = 1;
    time.nanoseconds = 0;
    userWaitset      = helper->userWaitset;
    ur               = U_RESULT_OK;

    while((helper->terminate == FALSE) && (ur == U_RESULT_OK)) {
        events = NULL;
        if(helper->waitset->timedWait == TRUE){
            ur = u_waitsetTimedWaitEvents(userWaitset, time,&events);
        } else {
            ur = u_waitsetWaitEvents(userWaitset,&events);
        }
        if(events  && (ur == U_RESULT_OK)){/* events may be null if waitset was deleted*/
            event = u_waitsetEvent(c_iterTakeFirst(events));

            while(event){
                /* Only dispatch event when durability is not terminating */
                if (d_durabilityGetState(durability) != D_STATE_TERMINATING){
                    we->action(we->dispatcher, event, we->usrData);
                }
                u_waitsetEventFree(event);
                event = u_waitsetEvent(c_iterTakeFirst(events));
            }
            c_iterFree(events);
        }
    }
    if(ur != U_RESULT_OK){
        d_printTimedEvent(durability, D_LEVEL_SEVERE,
            we->name,
            "Waitset no longer available (result: %d). Fatal error, terminating now...\n",
            ur);
        OS_REPORT_1(OS_ERROR, D_CONTEXT_DURABILITY, 0,
            "Waitset no longer available (result: %d). Fatal error, terminating now...\n",
            ur);
        d_durabilityTerminate(durability);
    }
    return NULL;
}
コード例 #2
0
ファイル: d_publisher.c プロジェクト: S73417H/opensplice
void
d_publisherInitMessage(
    d_publisher publisher,
    d_message message)
{
    d_message(message)->productionTimestamp = v_timeGet();
    d_message(message)->senderState = d_durabilityGetState(
                                            d_adminGetDurability(
                                                            publisher->admin));
}
コード例 #3
0
ファイル: d_waitset.c プロジェクト: xrl/opensplice_dds
static void*
d_waitsetEventHandlerRunToCompletion(
    void* userData)
{
    d_subscriber subscriber;
    d_durability durability;
    d_admin admin;
    d_waitset waitset;
    c_iter events = NULL;
    d_waitsetEntity we;
    c_time time;
    u_waitsetEvent event;

    waitset          = d_waitset(userData);
    subscriber       = d_waitsetGetSubscriber(waitset);
    admin            = d_subscriberGetAdmin(subscriber);
    durability       = d_adminGetDurability(admin);
    time.seconds     = 1;
    time.nanoseconds = 0;

    while(waitset->terminate == FALSE) {
        if(waitset->timedWait == TRUE){
            u_waitsetTimedWaitEvents(waitset->uwaitset, time,&events);
        } else {
            u_waitsetWaitEvents(waitset->uwaitset,&events);
        }
        if(d_durabilityGetState(durability) != D_STATE_TERMINATING){
            if(waitset->terminate == FALSE){
                d_lockLock(d_lock(waitset));

                event = u_waitsetEvent(c_iterTakeFirst(events));

                while(event){
                    we = c_iterResolve(waitset->entities, d_waitsetEntityFind, event->entity);

                    if(we){
                        we->action(we->dispatcher, event, we->usrData);
                    }
                    u_waitsetEventFree(event);
                    event = u_waitsetEvent(c_iterTakeFirst(events));
                }
            }
            d_lockUnlock(d_lock(waitset));
        }
        if(events){/* events may be null if waitset was deleted */
            c_iterFree(events);
        }
    }
    return NULL;
}
コード例 #4
0
static c_bool
isFellowStateCompatible(
    d_durability durability,
    d_fellow fellow)
{
    d_serviceState state, fellowState;
    c_bool allowed;

    allowed     = FALSE;
    fellowState = d_fellowGetState(fellow);
    state       = d_durabilityGetState(durability);

    switch(state){
        case D_STATE_INIT:
        case D_STATE_DISCOVER_FELLOWS_GROUPS:
            switch(fellowState){
                case D_STATE_INIT:
                case D_STATE_DISCOVER_FELLOWS_GROUPS:
                case D_STATE_INJECT_PERSISTENT:
                case D_STATE_FETCH_INITIAL:
                case D_STATE_FETCH:
                case D_STATE_ALIGN:
                case D_STATE_FETCH_ALIGN:
                case D_STATE_COMPLETE:
                case D_STATE_DISCOVER_LOCAL_GROUPS:
                   allowed = TRUE;
                    break;
                case D_STATE_DISCOVER_PERSISTENT_SOURCE:
                case D_STATE_TERMINATING:
                case D_STATE_TERMINATED:
                    allowed = FALSE;
                    break;
                default:
                    assert(FALSE);
                    allowed = FALSE;
                    break;
            }
            break;
        case D_STATE_INJECT_PERSISTENT:
        case D_STATE_DISCOVER_LOCAL_GROUPS:
        case D_STATE_FETCH_INITIAL:
        case D_STATE_FETCH:
        case D_STATE_ALIGN:
        case D_STATE_FETCH_ALIGN:
        case D_STATE_COMPLETE:
            switch(fellowState){
                case D_STATE_INIT:
                case D_STATE_DISCOVER_FELLOWS_GROUPS:
                case D_STATE_COMPLETE: /* TODO: need to allow other states too? */
                    allowed = TRUE;
                    break;
                default:
                    allowed = FALSE;
                    break;
            }
            break;
        case D_STATE_DISCOVER_PERSISTENT_SOURCE:
        case D_STATE_TERMINATING:
        case D_STATE_TERMINATED:
            allowed = FALSE;
            break;
        default:
            assert(FALSE);
            allowed = FALSE;
            break;
    }

    return TRUE;
}
コード例 #5
0
void
d_nameSpacesListenerAction(
    d_listener listener,
    d_message message)
{
    d_durability durability;
    d_admin admin;
    d_publisher publisher;
    d_fellow fellow;
    c_bool allowed;
    d_nameSpace nameSpace, localNameSpace, oldFellowNameSpace;
    c_ulong count;
    d_configuration config;
    d_nameSpacesRequest nsRequest;
    d_networkAddress sender;
    d_subscriber subscriber;
    d_sampleChainListener sampleChainListener;
    struct compatibilityHelper helper;
    d_adminStatisticsInfo info;
    c_bool added;
    os_time srcTime , curTime, difTime, maxDifTime;
    struct checkFellowMasterHelper fellowMasterHelper;
    d_name role;
    c_iter fellowNameSpaces;
    d_nameSpace ns;

    assert(d_listenerIsValid(d_listener(listener), D_NAMESPACES_LISTENER));

    admin               = d_listenerGetAdmin(listener);
    publisher           = d_adminGetPublisher(admin);
    durability          = d_adminGetDurability(admin);
    config              = d_durabilityGetConfiguration(durability);
    fellowNameSpaces    = NULL;

    d_printTimedEvent         (durability, D_LEVEL_FINE,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Received nameSpace from fellow %d (his master: %d, confirmed: %d, mergeState: %s, %d).\n",
                               message->senderAddress.systemId,
                               d_nameSpaces(message)->master.systemId,
                               d_nameSpaces(message)->masterConfirmed,
                               d_nameSpaces(message)->state.role,
                               d_nameSpaces(message)->state.value);

    sender = d_networkAddressNew(message->senderAddress.systemId,
                               message->senderAddress.localId,
                               message->senderAddress.lifecycleId);

    fellow = d_adminGetFellow(admin, sender);

    if(!fellow){
        d_printTimedEvent (durability, D_LEVEL_FINE,
                           D_THREAD_NAMESPACES_LISTENER,
                           "Fellow %d unknown, administrating it.\n",
                           message->senderAddress.systemId);
        fellow = d_fellowNew(sender, message->senderState);
        d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());
        added = d_adminAddFellow(admin, fellow);

        if(added == FALSE){
            d_fellowFree(fellow);
            fellow = d_adminGetFellow(admin, sender);
            assert(fellow);
        } else {
            fellow = d_adminGetFellow(admin, sender); /*Do this to allow fellowFree at the end*/
            nsRequest = d_nameSpacesRequestNew(admin);
            d_messageSetAddressee(d_message(nsRequest), sender);
            d_publisherNameSpacesRequestWrite(publisher, nsRequest, sender);
            d_nameSpacesRequestFree(nsRequest);
        }
    }
    d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());

    nameSpace = d_nameSpaceFromNameSpaces(config, d_nameSpaces(message));

    if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){

        /* Get old namespace of fellow */
        oldFellowNameSpace = d_nameSpaceCopy (d_fellowGetNameSpace (fellow, nameSpace));

        /* Update master of fellow nameSpace */
        added = d_fellowAddNameSpace(fellow, nameSpace);

        /* Create namespace with local policy (if a match exists) */
        localNameSpace = d_nameSpaceNew (config, d_nameSpaceGetName(nameSpace));

        /* If namespace is created, add to administration */
        if (localNameSpace) {
            /* Copy partitions to local nameSpace */
            d_nameSpaceCopyPartitions (localNameSpace, nameSpace);
            d_adminAddNameSpace (admin, localNameSpace);
            d_nameSpaceFree (localNameSpace);
        }

        /* If fellow is master for a namespace, report it to admin */
        fellowMasterHelper.admin = admin;
        fellowMasterHelper.fellow = d_fellowGetAddress(fellow);
        fellowMasterHelper.oldNameSpace = oldFellowNameSpace;
        checkFellowMasterWalk (nameSpace, &fellowMasterHelper);
        d_free (fellowMasterHelper.fellow);

        /* If the namespace was not added to the fellow (because it already existed there), free it */
        if(!added){
            d_nameSpaceFree(nameSpace);
        }

        d_nameSpaceFree (oldFellowNameSpace);

    } else {
        info = d_adminStatisticsInfoNew();
        d_fellowSetExpectedNameSpaces(fellow, d_nameSpaces(message)->total);
        d_fellowAddNameSpace(fellow, nameSpace);
        count = d_fellowNameSpaceCount(fellow);

        if(count == d_nameSpaces(message)->total){
            allowed = isFellowStateCompatible(durability, fellow);

            if(allowed == TRUE){
                config = d_durabilityGetConfiguration(durability);
                helper.fellow = fellow;
                helper.compatible = TRUE;

                d_adminNameSpaceWalk (admin, areFellowNameSpacesCompatible, &helper);

                if(helper.compatible == TRUE){

                    if(config->timeAlignment == TRUE){
                        curTime.tv_sec     = d_readerListener(listener)->lastInsertTime.seconds;
                        curTime.tv_nsec    = d_readerListener(listener)->lastInsertTime.nanoseconds;
                        srcTime.tv_sec     = d_readerListener(listener)->lastSourceTime.seconds;
                        srcTime.tv_nsec    = d_readerListener(listener)->lastSourceTime.nanoseconds;
                        maxDifTime.tv_sec  = 1; /*1s*/
                        maxDifTime.tv_nsec = 0;
                        difTime            = os_timeAbs(os_timeSub(curTime, srcTime));

                        if(os_timeCompare(difTime, maxDifTime) == OS_MORE){
                            d_printTimedEvent (durability, D_LEVEL_WARNING,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Estimated time difference including latency with " \
                               "fellow %d is %f seconds, which is larger then " \
                               "expected.\n",
                               message->senderAddress.systemId,
                               os_timeToReal(difTime));
                            OS_REPORT_2(OS_WARNING, D_CONTEXT, 0,
                                "Estimated time difference including latency " \
                                "with fellow '%d' is larger then expected " \
                                "(%f seconds). Durability alignment might not be " \
                                "reliable. Please align time between these nodes " \
                                "and restart.",
                                message->senderAddress.systemId,
                                os_timeToReal(difTime));
                        } else {
                            d_printTimedEvent (durability, D_LEVEL_FINER,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Estimated time difference including latency with " \
                               "fellow %d is %f seconds.\n",
                               message->senderAddress.systemId,
                               os_timeToReal(difTime));
                        }
                    }

                    /* Set role of fellow (take native role from namespace) */
                    role = d_nameSpaceGetRole(nameSpace);
                    d_fellowSetRole (fellow, role);
                    os_free (role);

                    d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_APPROVED);
                    info->fellowsApprovedDif += 1;
                    subscriber = d_adminGetSubscriber(admin);
                    sampleChainListener = d_subscriberGetSampleChainListener(subscriber);

                    if(sampleChainListener){
                        d_sampleChainListenerTryFulfillChains(sampleChainListener, NULL);
                    }

                    /* Check if the fellow is master for one or more namespaces and report this to admin */
                    fellowNameSpaces = c_iterNew(NULL);

                    /* Collect fellow namespaces */
                    d_fellowNameSpaceWalk (fellow, collectFellowNsWalk, fellowNameSpaces);

                    fellowMasterHelper.admin = admin;
                    fellowMasterHelper.fellow = d_fellowGetAddress(fellow);
                    fellowMasterHelper.oldNameSpace = NULL;
                    c_iterWalk (fellowNameSpaces, checkFellowMasterWalk, &fellowMasterHelper);

                    while ((ns = c_iterTakeFirst(fellowNameSpaces))) {
                        d_nameSpaceFree(ns);
                    }
                    c_iterFree(fellowNameSpaces);

                    d_free (fellowMasterHelper.fellow);

                } else {
                    info->fellowsIncompatibleDataModelDif += 1;

                    d_printTimedEvent (durability, D_LEVEL_WARNING,
                                   D_THREAD_NAMESPACES_LISTENER,
                                   "Communication with fellow %d NOT approved, because data model is not compatible\n",
                                   message->senderAddress.systemId);
                    d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL);
                }
            } else {
                info->fellowsIncompatibleStateDif += 1;
                d_printTimedEvent (durability, D_LEVEL_WARNING,
                                   D_THREAD_NAMESPACES_LISTENER,
                                   "Communication with fellow %d NOT approved, because state is not compatible my state: %d, fellow state: %d\n",
                                   message->senderAddress.systemId,
                                   d_durabilityGetState(durability),
                                   message->senderState);
                d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_STATE);
            }
        } else {
            d_printTimedEvent (durability, D_LEVEL_WARNING,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Received %u of %u nameSpaces from fellow %u.\n",
                               count, d_nameSpaces(message)->total,
                               message->senderAddress.systemId);
        }
        d_adminUpdateStatistics(admin, info);
        d_adminStatisticsInfoFree(info);
    }
    d_fellowFree(fellow);
    d_networkAddressFree(sender);

    return;
}
コード例 #6
0
ファイル: d_misc.c プロジェクト: xrl/opensplice_dds
void
d_printState(
    d_durability durability,
    d_configuration config,
    const char* threadName)
{
    os_time time;
    d_serviceState kind;
    const c_char* state;

    if(config->tracingOutputFile){
        kind = d_durabilityGetState(durability);

        switch(kind){
            case D_STATE_INIT:
                state = "INIT";
                break;
            case D_STATE_DISCOVER_FELLOWS_GROUPS:
                state = "DISCOVER_FELLOWS_GROUPS";
                break;
            case D_STATE_DISCOVER_PERSISTENT_SOURCE:
                state = "DISCOVER_PERSISTENT_SOURCE";
                break;
            case D_STATE_INJECT_PERSISTENT:
                state = "INJECT_PERSISTENT";
                break;
            case D_STATE_DISCOVER_LOCAL_GROUPS:
                state = "DISCOVER_LOCAL_GROUPS";
                break;
            case D_STATE_FETCH_INITIAL:
                state = "FETCH_INITIAL";
                break;
            case D_STATE_FETCH:
                state = "FETCH";
                break;
            case D_STATE_ALIGN:
                state = "ALIGN";
                break;
            case D_STATE_FETCH_ALIGN:
                state = "FETCH_ALIGN";
                break;
            case D_STATE_COMPLETE:
                state = "COMPLETE";
                break;
            case D_STATE_TERMINATING:
                state = "TERMINATING";
                break;
            case D_STATE_TERMINATED:
                state = "TERMINATED";
                break;
            default:
                state = "<<UNKNOWN>>";
                break;
        }

        if(config->tracingTimestamps == TRUE){
            time = os_timeGet();

            if(config->tracingRelativeTimestamps == TRUE){
                time = os_timeSub(time, config->startTime);
            }
            fprintf(config->tracingOutputFile, "%d.%9.9d %s (%s) -> ",
                    time.tv_sec, time.tv_nsec, state, threadName);
        } else {
            fprintf(config->tracingOutputFile, "%s (%s) -> ", state, threadName);
        }
    }
}
コード例 #7
0
static void*
d_groupCreationQueueRun(
    void* userData)
{
    d_groupCreationQueue queue;
    c_iter groupsToCreate, reinsert;
    d_group group, localGroup;
    d_durability durability;
    d_durabilityKind kind;
    u_participant uservice;
    c_char *partition, *topic;
    v_duration duration;
    u_group ugroup;
    c_long creationCountVolatile, creationCountTransient, creationCountPersistent;
    c_ulong maxBurst;
    os_time sleepTime, maxBurstSleepTime;
    c_bool update;

    sleepTime.tv_sec          = 1;
    sleepTime.tv_nsec         = 0;
    duration.seconds          = 0;
    duration.nanoseconds      = 5000000; /*5ms*/
    creationCountVolatile     = 0;
    creationCountTransient    = 0;
    creationCountPersistent   = 0;
    maxBurstSleepTime.tv_sec  = 0;
    maxBurstSleepTime.tv_nsec = 10000000; /*10ms*/

    queue                = d_groupCreationQueue(userData);
    groupsToCreate       = c_iterNew(NULL);
    reinsert             = c_iterNew(NULL);
    durability           = d_adminGetDurability(queue->admin);
    uservice             = u_participant(d_durabilityGetService(durability));

    d_waitForCompletenessDCPSTopic(queue);

    while(queue->terminate == FALSE) {
        d_lockLock(d_lock(queue));

        queue->groupsToCreateVolatile -= creationCountVolatile;
        assert(queue->groupsToCreateVolatile >= 0);
        queue->groupsToCreateTransient -= creationCountTransient;
        assert(queue->groupsToCreateTransient >= 0);
        queue->groupsToCreatePersistent -= creationCountPersistent;
        assert(queue->groupsToCreatePersistent >= 0);

        group = d_group(c_iterTakeFirst(queue->groups));

        while(group){
            groupsToCreate = c_iterInsert(groupsToCreate, group);
            group = d_group(c_iterTakeFirst(queue->groups));
        }
        assert((queue->groupsToCreateVolatile +
                queue->groupsToCreateTransient +
                queue->groupsToCreatePersistent) ==
               c_iterLength(groupsToCreate));

        durability = d_adminGetDurability(queue->admin);
        d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue);

        d_lockUnlock(d_lock(queue));

        creationCountVolatile   = 0;
        creationCountTransient  = 0;
        creationCountPersistent = 0;
        maxBurst                = 10;

        group = c_iterTakeFirst(groupsToCreate);

        while(group && (queue->terminate == FALSE)){
            partition  = d_groupGetPartition(group);
            topic      = d_groupGetTopic(group);
            kind       = d_groupGetKind(group);
            localGroup = d_adminGetLocalGroup(queue->admin, partition, topic, kind);
            update     = FALSE;

            if(localGroup) {
                d_printTimedEvent(durability,
                            D_LEVEL_FINE,
                            D_THREAD_GROUP_CREATION,
                            "Remote group %s.%s has already been created locally.\n",
                            partition, topic);
                update = TRUE;
            } else {
                ugroup = u_groupNew(uservice, partition, topic, duration);

                if(ugroup){
                    d_printTimedEvent(durability,
                                    D_LEVEL_FINE,
                                    D_THREAD_GROUP_CREATION,
                                    "Remote group %s.%s created locally.\n",
                                    partition, topic);
                    update = TRUE;
                    u_entityFree(u_entity(ugroup));
                    maxBurst--;

                    if(maxBurst == 0){
                        os_nanoSleep(maxBurstSleepTime);
                        maxBurst = 10;
                    }
                } else {
                    maxBurst++;
                    d_printTimedEvent(durability, D_LEVEL_FINE,
                                D_THREAD_GROUP_CREATION,
                                "Remote group %s.%s could not be created locally.\n",
                                partition, topic);

                    if(d_durabilityGetState(durability) == D_STATE_COMPLETE){
                        d_printTimedEvent(durability, D_LEVEL_FINE,
                                D_THREAD_GROUP_CREATION,
                                "I am complete so it will not be available anymore.\n");
                        update = TRUE;
                    } else if(d_adminGetFellowCount(queue->admin) == 0){
                        d_printTimedEvent(durability, D_LEVEL_WARNING,
                                D_THREAD_GROUP_CREATION,
                                "No fellows available to provide me with group information. " \
                                "Ignoring group.\n",
                                partition, topic);
                        update = TRUE;
                    } else {
                        reinsert = c_iterInsert(reinsert, group);
                    }
                }
            }
            if(update){
                switch(d_groupGetKind(group)){
                case D_DURABILITY_VOLATILE:
                    creationCountVolatile++;
                    break;
                case D_DURABILITY_TRANSIENT:
                case D_DURABILITY_TRANSIENT_LOCAL:
                    creationCountTransient++;
                    break;
                case D_DURABILITY_PERSISTENT:
                    creationCountPersistent++;
                    break;
                default:
                    assert(FALSE);
                    break;
                }
                d_groupFree(group);
            }
            os_free(partition);
            os_free(topic);
            group = c_iterTakeFirst(groupsToCreate);
        }
        group = d_group(c_iterTakeFirst(reinsert));

        while(group){
            groupsToCreate = c_iterInsert(groupsToCreate, group);
            group = d_group(c_iterTakeFirst(reinsert));
        }
        if(queue->terminate == FALSE){
            os_nanoSleep(sleepTime);
        }
    }

    group = d_group(c_iterTakeFirst(groupsToCreate));

    while(group) {
        d_groupFree(group);
        group = d_group(c_iterTakeFirst(groupsToCreate));
    }
    c_iterFree(groupsToCreate);
    c_iterFree(reinsert);

    d_lockLock(d_lock(queue));
    group = d_group(c_iterTakeFirst(queue->groups));

    while(group) {
        d_groupFree(group);
        group = d_group(c_iterTakeFirst(queue->groups));
    }
    d_lockUnlock(d_lock(queue));

    return NULL;
}