Пример #1
0
c_bool
d_readerRequestRemoveChain(
    d_readerRequest request,
    d_chain chain)
{
    d_chain found;
    c_bool result;

    assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE);
    assert(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE);

    if(request && chain){
        d_lockLock(d_lock(request));
        found = d_tableRemove(request->requests, chain);
        d_lockUnlock(d_lock(request));

        if(found){
            result = TRUE;
            d_chainFree(found);
        } else {
            result = FALSE;
        }
    } else {
        result = FALSE;
    }
    return result;
}
Пример #2
0
c_bool
d_readerRequestAddGroup(
    d_readerRequest request,
    d_group group)
{
    c_bool result;
    d_group found;

    assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE);

    if(request){
        d_lockLock(d_lock(request));
        found = d_tableInsert(request->groups, group);
        d_lockUnlock(d_lock(request));

        if(!found){
            d_objectKeep(d_object(group));
            result = TRUE;
        } else {
            result = FALSE;
        }
    } else {
        result = FALSE;
    }
    return result;
}
Пример #3
0
void
d_waitsetDeinit(
    d_object object)
{
    d_waitset waitset;
    d_waitsetEntity we;
    d_waitsetHelper helper;

    assert(d_objectIsValid(object, D_WAITSET) == TRUE);

    if(object){
        waitset = d_waitset(object);
        waitset->terminate = TRUE;

        if(waitset->runToCompletion == TRUE){
            if(os_threadIdToInteger(waitset->thread)) {
                u_waitsetNotify(waitset->uwaitset, NULL);
                os_threadWaitExit(waitset->thread, NULL);
            }
        } else {
            if(waitset->threads){
                helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads));

                while(helper){
                    helper->terminate = TRUE;
                    u_waitsetNotify(helper->userWaitset, NULL);
                    os_threadWaitExit(helper->tid, NULL);
                    u_waitsetDetach(helper->userWaitset, u_entity(helper->entity->dispatcher));
                    u_waitsetFree(helper->userWaitset);
                    os_free(helper);
                    helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads));
                }
                c_iterFree(waitset->threads);
                waitset->threads = NULL;
            }
        }
        d_lockLock(d_lock(waitset));

        if(waitset->entities) {
            we = d_waitsetEntity(c_iterTakeFirst(waitset->entities));

            while(we) {
                if(waitset->runToCompletion == TRUE){
                    u_waitsetDetach(waitset->uwaitset, u_entity(we->dispatcher));
                }
                d_waitsetEntityFree(we);
                we = d_waitsetEntity(c_iterTakeFirst(waitset->entities));
            }
            c_iterFree(waitset->entities);
        }
        if(waitset->runToCompletion == TRUE){
            if(waitset->uwaitset) {
                u_waitsetFree(waitset->uwaitset);
            }
        }
        d_lockUnlock(d_lock(waitset));
    }
}
Пример #4
0
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;
}
Пример #5
0
c_bool
d_waitsetDetach(
    d_waitset waitset,
    d_waitsetEntity we)
{
    u_result ur;
    c_bool result = FALSE;
    int i;
    d_waitsetHelper helper;

    helper = NULL;

    assert(d_objectIsValid(d_object(waitset), D_WAITSET) == TRUE);
    assert(d_objectIsValid(d_object(we), D_WAITSET_ENTITY) == TRUE);

    if(waitset && we){
        d_lockLock(d_lock(waitset));

        if(c_iterContains(waitset->entities, we) == TRUE) {
            if(waitset->runToCompletion == TRUE){
                ur = u_waitsetDetach(waitset->uwaitset, u_entity(we->dispatcher));
            } else {
                for(i=0; i<c_iterLength(waitset->threads) && !helper; i++){
                    helper = d_waitsetHelper(c_iterObject(waitset->threads, i));

                    if(helper->entity != we){
                        helper = NULL;
                    }
                }
                assert(helper);
                c_iterTake(waitset->threads, helper);
                helper->terminate = TRUE;
                u_waitsetNotify(helper->userWaitset, NULL);
                os_threadWaitExit(helper->tid, NULL);
                ur = u_waitsetDetach(helper->userWaitset, u_entity(we->dispatcher));
                u_waitsetFree(helper->userWaitset);
                os_free(helper);
            }
            if(ur == U_RESULT_OK) {
                c_iterTake(waitset->entities, we);
                we->waitset = NULL;
                result = TRUE;
            }
        }
        d_lockUnlock(d_lock(waitset));
    }
    return result;
}
Пример #6
0
c_bool
d_readerRequestAreGroupsComplete(
    d_readerRequest request)
{
    c_bool result;

    assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE);

    if(request){
        d_lockLock(d_lock(request));
        result = d_tableWalk(request->groups, checkCompleteness, NULL);
        d_lockUnlock(d_lock(request));
    } else {
        result = FALSE;
    }
    return result;
}
Пример #7
0
c_bool
d_readerRequestHasChains(
    d_readerRequest request)
{
    c_bool result;

    assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE);

    if(request){
        d_lockLock(d_lock(request));
        result = (d_tableSize(request->requests) != 0);
        d_lockUnlock(d_lock(request));
    } else {
        result = FALSE;
    }
    return result;
}
Пример #8
0
d_table
d_readerRequestGetGroups(
    d_readerRequest request)
{
    d_table result;

    assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE);

    if(request){
        d_lockLock(d_lock(request));
        result = d_tableNew(d_groupCompare, d_groupFree);
        d_tableWalk(request->groups, addGroup, result);
        d_lockUnlock(d_lock(request));
    } else {
        result = NULL;
    }
    return result;
}
Пример #9
0
c_bool
d_groupCreationQueueAdd(
    d_groupCreationQueue queue,
    d_group group)
{
    c_bool result;
    d_group found;
    d_durability durability;
    assert(d_objectIsValid(d_object(queue), D_GROUP_CREATION_QUEUE) == TRUE);

    result = FALSE;

    if(queue) {
        d_lockLock(d_lock(queue));

        found = c_iterResolve(queue->groups, (c_iterResolveCompare)compareGroups, group);

        if(found == NULL){
            queue->groups = c_iterInsert(queue->groups, group);

            switch(d_groupGetKind(group)){
            case D_DURABILITY_VOLATILE:
                queue->groupsToCreateVolatile++;
                break;
            case D_DURABILITY_TRANSIENT:
            case D_DURABILITY_TRANSIENT_LOCAL:
                queue->groupsToCreateTransient++;
                break;
            case D_DURABILITY_PERSISTENT:
                queue->groupsToCreatePersistent++;
                break;
            default:
                assert(FALSE);
                break;
            }
            durability = d_adminGetDurability(queue->admin);
            d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue);
            result = TRUE;
        }
        d_lockUnlock(d_lock(queue));

    }
    return result;
}
Пример #10
0
void
d_readerRequestRemoveGroup(
    d_readerRequest request,
    d_group group)
{
    d_group dgroup;

    assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE);

    if(request){
        d_lockLock(d_lock(request));
        dgroup = d_tableRemove(request->groups, group);
        d_lockUnlock(d_lock(request));

        if(dgroup){
            d_groupFree(dgroup);
        }
    }
    return;
}
Пример #11
0
c_bool
d_groupCreationQueueIsEmpty(
    d_groupCreationQueue queue)
{
    c_bool result;

    assert(d_objectIsValid(d_object(queue), D_GROUP_CREATION_QUEUE) == TRUE);

    d_lockLock(d_lock(queue));

    if((queue->groupsToCreateVolatile == 0) &&
       (queue->groupsToCreateTransient == 0) &&
       (queue->groupsToCreatePersistent == 0)){
        result = TRUE;
    } else {
        result = FALSE;
    }
    d_lockUnlock(d_lock(queue));

    return result;
}
Пример #12
0
c_bool
d_waitsetAttach(
    d_waitset waitset,
    d_waitsetEntity we)
{
    c_bool result = FALSE;
    u_result ur;
    os_result osr;
    d_waitsetHelper helper;
    c_ulong mask;
    d_admin admin;
    d_durability durability;

    assert(d_objectIsValid(d_object(waitset), D_WAITSET) == TRUE);
    assert(d_objectIsValid(d_object(we), D_WAITSET_ENTITY) == TRUE);

    if(waitset && we){
        d_lockLock(d_lock(waitset));

        if(!we->waitset) {
            if(c_iterContains(waitset->entities, we) == FALSE) {
                waitset->entities = c_iterInsert(waitset->entities, we);
                if(waitset->runToCompletion == TRUE){
                    ur = u_waitsetAttach(waitset->uwaitset, u_entity(we->dispatcher),
                             (c_voidp)we->dispatcher);

                    if(ur == U_RESULT_OK) {
                        we->waitset = waitset;
                        result = TRUE;
                    }
                } else {
                    admin = d_subscriberGetAdmin(waitset->subscriber);
                    durability = d_adminGetDurability(admin);

                    helper = os_malloc(C_SIZEOF(d_waitsetHelper));
                    helper->waitset     = waitset;
                    helper->entity      = we;
                    helper->terminate   = FALSE;
                    helper->tid         = OS_THREAD_ID_NONE;
                    helper->userWaitset = u_waitsetNew(u_participant(d_durabilityGetService(durability)));

                    mask = V_EVENT_DATA_AVAILABLE;
                    mask |= V_EVENT_NEW_GROUP;
                    mask |= V_EVENT_HISTORY_DELETE;
                    mask |= V_EVENT_HISTORY_REQUEST;
                    mask |= V_EVENT_PERSISTENT_SNAPSHOT;
                    mask |= V_EVENT_TRIGGER;
                    u_waitsetSetEventMask(helper->userWaitset, mask);
                    ur = u_waitsetAttach(helper->userWaitset, u_entity(we->dispatcher),
                             (c_voidp)we->dispatcher);

                    if(ur != U_RESULT_OK) {
                        assert(FALSE);
                    } else {
                        result = TRUE;
                    }
                    if(result){
                        waitset->threads  = c_iterInsert(waitset->threads, helper);

                        osr = os_threadCreate(&(helper->tid), we->name, &(we->attr),
                                    d_waitsetEventHandler, helper);

                        if(osr != os_resultSuccess){
                            c_iterTake(waitset->threads, helper);
                            u_waitsetDetach(helper->userWaitset, u_entity(we->dispatcher));
                            u_waitsetFree(helper->userWaitset);
                            os_free(helper);
                            result = FALSE;
                        }
                    } else {
                        u_waitsetFree(helper->userWaitset);
                        os_free(helper);
                    }

                }
            }
        }
        d_lockUnlock(d_lock(waitset));
    }
    return result;
}
Пример #13
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;
}