Beispiel #1
0
c_bool
v_readerWaitForHistoricalData(
    v_reader r,
    c_time timeout)
{
    struct historicalWaitArg arg;
    c_iter entries;
    c_object e;

    v_readerEntrySetLock(r);
    entries = c_select(r->entrySet.entries, 0);
    v_readerEntrySetUnlock(r);

    arg._expire_time = c_timeAdd(v_timeGet(), timeout);
    arg._status = TRUE;

    e = c_iterTakeFirst(entries);
    while (e != NULL) {
        if (arg._status == TRUE) {
            if (r->qos->durability.kind == V_DURABILITY_VOLATILE) {
                getHistoricalData(e, NULL);
            }
            waitForHistoricalData(e, &arg);
        }
        c_free(e);
        e = c_iterTakeFirst(entries);
    }
    c_iterFree(entries);

    return(arg._status);
}
Beispiel #2
0
static void
v_networkQueueUpdateNextWakeup(
    v_networkQueue queue,
    c_bool *hasChanged)
{
    c_time now;
    c_time soon;
    c_time newWakeup;
    c_ulonglong msecsTime;
    c_ulonglong msecsResult;
    c_ulonglong msecsLeftOver;
    static c_time minSleepTime = MIN_SLEEPTIME;
    
    *hasChanged = FALSE;
    if (queue->periodic) {
        now = v_timeGet();
        soon = c_timeAdd(now, minSleepTime);
        TIME_TO_MSEC(soon, msecsTime);
        /* Do a ++ because we are doing a ceil and TIME_TO_MSEC is doing a trunc.
         * Only if time was an exact multiple of milliseconds, this approach is
         * not completely correct. But it saves us the hassle and this works fine */
        msecsTime++;
        msecsLeftOver = (msecsTime - queue->phaseMilliSeconds) % queue->msecsResolution;
        msecsResult = msecsTime - msecsLeftOver + queue->msecsResolution;
        MSEC_TO_TIME(msecsResult, newWakeup);
        if (c_timeCompare(newWakeup,queue->nextWakeup) == C_GT) {
            queue->nextWakeup = newWakeup;
            *hasChanged = TRUE;
        }
    }
}
Beispiel #3
0
void
v_messageSetAllocTime(
    v_message _this)
{
    if (_this) {
        _this->allocTime = v_timeGet();
    }
}
Beispiel #4
0
void
v_instanceUpdate(
    v_instance instance)
{
    assert(C_TYPECHECK(instance, v_instance));

    instance->lastCheckTime = v_timeGet();
}
Beispiel #5
0
void
v_instanceUpdate(
    v_instance instance)
{
    assert(C_TYPECHECK(instance, v_instance));

    instance->lastDeadlineResetTime = v_timeGet();
}
Beispiel #6
0
void
v_timedValueSetValue(
    v_timedValue *_this,
    c_ulong value)
{
    assert(_this != NULL);
    _this->value = value;
    _this->lastUpdate = v_timeGet();
}
Beispiel #7
0
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));
}
Beispiel #8
0
void
v_messageSetAllocTime(
    v_message _this)
{
#ifndef _NAT_
    if (_this) {
        _this->allocTime = v_timeGet();
    }
#endif    
}
Beispiel #9
0
void
v_leaseUpdate(
    v_lease lease)
{
    if (lease != NULL) {
        assert(C_TYPECHECK(lease, v_lease));

        v_leaseLock(lease);
        lease->expiryTime = c_timeAdd(v_timeGet(), lease->duration);
        v_leaseUnlock(lease);
    }
}
Beispiel #10
0
void
v_lifespanAdminTakeExpired(
    v_lifespanAdmin admin,
    v_lifespanSampleAction action,
    c_voidp arg)
{
    c_bool proceed;
    v_lifespanSample removed;
    c_time now;
    c_equality eq;

    assert(C_TYPECHECK(admin,v_lifespanAdmin));

    CHECK_ADMIN(admin, NULL);
    if (admin->head != NULL) {
        now = v_timeGet();
        eq = c_timeCompare(now, admin->head->expiryTime);
        proceed = TRUE;
        while ((proceed) && (eq != C_LT /* >= */) && (admin->head != NULL)) {
            removed = admin->head;
            if (action) {
                proceed = action(removed, arg);
            } else {
                proceed = TRUE;
            }
            if ((proceed) && (removed == admin->head)) {
               /* The action routine might have already removed the sample, so 
                * we check if the head of the list has not changed! 
                */
                admin->head = removed->next; /* transfer refcount */
                removed->next = NULL;
                if (admin->head == NULL) {
                    assert(removed == admin->tail);
                    c_free(admin->tail);
                    admin->tail = NULL;
                    proceed = FALSE;
                } else {
                    admin->head->prev = NULL;
                }
                assert(admin->sampleCount > 0);
                admin->sampleCount--;
                CHECK_ADMIN(admin, removed);
                c_free(removed);
            }
            if (admin->head != NULL) {
                eq = c_timeCompare(now, admin->head->expiryTime);
            }
        }
    }
    CHECK_ADMIN(admin, NULL);
}
Beispiel #11
0
v_networkReaderWaitResult
v_networkReaderWaitDelayed(
    v_networkReader reader,
    c_ulong queueId,
    v_networkQueue *queue)
{
    c_time sleep;
    /* Simply sleeping here for resolution time, is not correct.
    We should wakeup on, or just after the next wakeuptime.*/
    sleep = c_timeSub(v_networkQueue(reader->queues[queueId-1])->nextWakeup, v_timeGet());
    c_timeNanoSleep(sleep);

    return V_WAITRESULT_TIMEOUT | v_networkReaderWait(reader, queueId, queue);
}
Beispiel #12
0
void
v_participantDeleteHistoricalData(
    v_participant participant,
    const c_char* partitionExpr,
    const c_char* topicExpr)
{
    c_iter matchingGroups;
    v_group group;
    c_time t;
    c_value params[2];
    C_STRUCT(v_event) event;
    C_STRUCT(v_historyDeleteEventData) hde;

    assert(participant != NULL);
    assert(C_TYPECHECK(participant, v_participant));
    assert(partitionExpr);
    assert(topicExpr);

    if(partitionExpr && topicExpr){
        params[0]  = c_stringValue((c_string)partitionExpr);
        params[1]  = c_stringValue((c_string)topicExpr);

        c_lockRead(&participant->lock);
        t = v_timeGet();
        matchingGroups = v_groupSetSelect(
                                v_objectKernel(participant)->groupSet,
                                "partition.name like %0 AND topic.name like %1",
                                params);
        c_lockUnlock(&participant->lock);

        group = v_group(c_iterTakeFirst(matchingGroups));
        while(group){
            v_groupDeleteHistoricalData(group, t);
            c_free(group);
            group = v_group(c_iterTakeFirst(matchingGroups));
        }
        c_iterFree(matchingGroups);


        hde.partitionExpression = (c_char *)partitionExpr;
        hde.topicExpression = (c_char *)topicExpr;
        hde.deleteTime = t;
        event.kind = V_EVENT_HISTORY_DELETE;
        event.source = v_publicHandle(v_public(participant));
        event.userData = &hde;
        v_observableNotify(v_observable(v_objectKernel(participant)),&event);
    }
    return;
}
Beispiel #13
0
void
v_leaseInit(
    v_lease _this,
    v_kernel k,
    v_duration leaseDuration)
{
    if (_this != NULL)
    {
        assert(C_TYPECHECK(_this, v_lease));

        c_mutexInit(&_this->mutex,SHARED_MUTEX);
        _this->expiryTime = c_timeAdd(v_timeGet(), leaseDuration);
        _this->duration = leaseDuration;
        _this->observers = c_setNew(v_kernelType(k, K_LEASEMANAGER));
    }
}
Beispiel #14
0
void
v_unregisterBuiltinTopic(
    v_kernel k,
    enum v_infoId id,
    v_message msg)
{
    v_writer writer;

    if (msg != NULL) {
        writer = v_builtinWriterLookup(k->builtin,id);
        if (writer != NULL) {
            /* No need to fill writerGID, this is done by the writer */
            v_writerUnregister(writer,msg,v_timeGet(),NULL);
        }
    }
}
Beispiel #15
0
v_result v_participantWriteCandMCommand(v_participant participant, v_message msg)
{
   v_writeResult wres;
   v_writer builtinWriter;

   assert(participant != NULL);
   assert(C_TYPECHECK(participant,v_participant));
   assert(msg != NULL);
   assert(C_TYPECHECK(msg,v_message));

   builtinWriter = v_builtinWriterLookup(v_objectKernel(participant)->builtin,
                                         V_C_AND_M_COMMAND_ID);
   wres = v_writerWrite(builtinWriter, msg, v_timeGet(), NULL);
   return ( wres == V_WRITE_SUCCESS
            ? V_RESULT_OK
              : V_RESULT_INTERNAL_ERROR );
}
Beispiel #16
0
static v_message
createUnregisterMessage(
    v_group group,
    v_message message)
{
    c_array            messageKeyList;
    c_long                i, nrOfKeys;
    v_message            unregisterMessage;

    assert(!v_stateTest(v_nodeState(message), L_UNREGISTER));

    /* Create new message objec */
    unregisterMessage = v_topicMessageNew
                                (group->topic);

    /* Copy keyvalues to unregistermessage */
    messageKeyList = v_topicMessageKeyList(v_groupTopic(group));
    nrOfKeys = c_arraySize(messageKeyList);
    for (i=0;i<nrOfKeys;i++) {
        c_fieldAssign (messageKeyList[i],
                unregisterMessage,
                c_fieldValue(messageKeyList[i],message));
    }

    /* Set instance & writer GID */
    unregisterMessage->writerGID =
            message->writerGID;
    unregisterMessage->writerInstanceGID =
            message->writerInstanceGID;

    /* Copy messageQos */
    c_keep (message->qos);
    unregisterMessage->qos = message->qos;

    /* Set nodestate to unregister */
    v_nodeState(unregisterMessage) = L_UNREGISTER;

    unregisterMessage->writeTime = v_timeGet();
#ifndef _NAT_
    unregisterMessage->allocTime = unregisterMessage->writeTime;
#endif

    return unregisterMessage;
}
Beispiel #17
0
void
cmx_writerUnregisterCopy(
    v_entity entity,
    c_voidp args)
{
    v_writer kw;
    v_message message;
    void *to;
    sd_serializer ser;
    sd_serializedData data;
    sd_validationResult valResult;
    struct cmx_writerArg *arg;
    
    arg = (struct cmx_writerArg *)args;
    
    kw = v_writer(entity);
    message = v_topicMessageNew(kw->topic);
    to = C_DISPLACE(message,v_topicDataOffset(kw->topic));
    
    ser = sd_serializerXMLNewTyped(v_topicDataType(kw->topic));
    data = sd_serializerFromString(ser, arg->result);
    sd_serializerDeserializeIntoValidated(ser, data, to);
    valResult = sd_serializerLastValidationResult(ser);
        
    if(valResult != SD_VAL_SUCCESS){
        OS_REPORT_2(OS_ERROR, CM_XML_CONTEXT, 0, 
                    "Unregister of userdata failed.\nReason: %s\nError: %s\n",
                    sd_serializerLastValidationMessage(ser),
                    sd_serializerLastValidationLocation(ser));           
        arg->success = CMX_RESULT_FAILED;
    } else {
        arg->success = CMX_RESULT_OK;
    }
    sd_serializedDataFree(data);
    sd_serializerFree(ser);
    
    /* Note that the last param of v_writerWriteDispose is NULL,
       performance can be improved if the instance is provided. */    
    v_writerUnregister(kw,message,v_timeGet(),NULL);
    c_free(message);
}
Beispiel #18
0
static c_bool
d_statusListenerRemoveDeadFellows(
    d_action action,
    c_bool terminate)
{
    d_admin admin;
    d_configuration config;
    d_timestamp removeTime;
    d_durability durability;
    c_bool result = FALSE;

    admin      = d_admin(d_actionGetArgs(action));

    if(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE){
        if(terminate == FALSE){
            config = d_durabilityGetConfiguration(d_adminGetDurability(admin));

            removeTime.seconds = config->heartbeatExpiryTime.tv_sec;
            removeTime.nanoseconds = config->heartbeatExpiryTime.tv_nsec;

            while (removeTime.nanoseconds >= 1000000000) {
                removeTime.seconds += 1;
                removeTime.nanoseconds -= 1000000000;
            }
            /*
             * Remove the fellow if it didn't report since current time minus
             * the heartbeat period times the maximum nomber of heartbeat
             * misses.
             */
            durability = d_adminGetDurability(admin);

            if(d_durabilityMustTerminate(durability) == FALSE){
                removeTime = c_timeSub(v_timeGet(), removeTime);
                d_adminCleanupFellows(admin, removeTime);
            }
            result = TRUE;
        }
    }
    return result;
}
Beispiel #19
0
void
v_leaseRenew(
    v_lease lease,
    v_duration leaseDuration)
{
    c_iter observers = NULL;
    v_leaseManager observer;

    if (lease != NULL) {
        assert(C_TYPECHECK(lease, v_lease));

        v_leaseLock(lease);
        lease->expiryTime = c_timeAdd(v_timeGet(), leaseDuration);
        lease->duration = leaseDuration;
        /* Collect all observers, so they can be notified of the lease change
         * Must do a seperate collect as the lease mutex is 'lower' then the
         * leaseManager mutex. So to prevent deadlock we can not directly notify
         * the lease manager as we walk the collection
         */
        if(lease->observers)
        {
            c_walk(lease->observers, v_leaseCollectObservers, &observers);
        }
        v_leaseUnlock(lease);
        if(observers)
        {
            observer = v_leaseManager(c_iterTakeFirst(observers));
            while (observer != NULL)
            {
                v_leaseManagerNotify(
                    observer,
                    lease,
                    V_EVENT_LEASE_RENEWED);
                c_free(observer);
                observer = v_leaseManager(c_iterTakeFirst(observers));
            }
            c_iterFree(observers);
        }
    }
}
Beispiel #20
0
static c_bool
waitForHistoricalData(
    c_object o,
    c_voidp arg)
{
    v_entry entry;
    c_iter proxies;
    v_proxy proxy;
    v_group group;
    c_time waitTime;
    struct historicalWaitArg *parms = (struct historicalWaitArg *)arg;

    assert(o != NULL);
    assert(arg != NULL);

    entry = v_entry(o);
    assert(entry != NULL);
    assert(C_TYPECHECK(entry,v_entry));

    proxies = c_select(entry->groups, 0);
    proxy = c_iterTakeFirst(proxies);
    while ((proxy != NULL) && (parms->_status == TRUE)) {
        group = v_group(v_proxyClaim(proxy));
        if (group) {
            if (group->complete == FALSE) {
                waitTime  = c_timeSub(parms->_expire_time, v_timeGet());
                if (c_timeCompare(waitTime, C_TIME_ZERO) == C_GT) {
                    parms->_status = v_groupWaitForComplete(group, waitTime);
                } else {
                    parms->_status = FALSE; /* time out */
                }
            }
            v_proxyRelease(proxy);
        }
        c_free(proxy);
        proxy = c_iterTakeFirst(proxies);
    }
    c_iterFree(proxies);
    return parms->_status;
}
Beispiel #21
0
v_networkQueue
v_networkQueueNew(
    c_base base,
    c_ulong queueSize,
    c_ulong priority,
    c_bool reliable,
    c_bool P2P,
    c_time resolution,
    v_networkQueueStatistics statistics)
{
    v_networkQueue result = NULL;
    c_type type;
    c_equality equality;
    c_bool hasChanged;
    c_time now;

    type = c_resolve(base, "kernelModule::v_networkQueue");
    assert(type);
    result = v_networkQueue(c_new(type));
    c_free(type);

    if (result) {
        /* Queue properties */
        result->maxMsgCount = queueSize;
        result->currentMsgCount = 0;
        /* Cached type */
        result->statusMarkerType = c_resolve(base, "kernelModule::v_networkStatusMarker");
        assert(result->statusMarkerType != NULL);
        result->sampleType = c_resolve(base, "kernelModule::v_networkQueueSample");
        assert(result->sampleType != NULL);
        /* Linked list of in-use marker items */
        result->firstStatusMarker = NULL;
        result->lastStatusMarker = NULL;
        /* Linked list of free marker and message items */
        result->freeStatusMarkers = NULL;
        result->freeSamples = NULL;
        /* Init cv stuff */
        c_mutexInit(&result->mutex, SHARED_MUTEX);
        c_condInit(&result->cv, &result->mutex, SHARED_COND);
        /* Currently no differentiation wrt qos */
        result->priority = priority;
        result->reliable = reliable;
        result->P2P = P2P;

        result->statistics = statistics;

        equality = c_timeCompare(C_TIME_ZERO, resolution);
        if (equality == C_EQ) {
            result->periodic = FALSE;
            result->resolution = C_TIME_INFINITE;
            result->msecsResolution = 0xFFFFFFFF;
            result->phaseMilliSeconds = 0;
            result->nextWakeup = C_TIME_INFINITE;
        } else {
            assert(equality == C_LT);
            result->periodic = TRUE;
            result->resolution = resolution;
            TIME_TO_MSEC(resolution, result->msecsResolution);        
            /* A semi-random phase to avoid wake-ups at the same time */
            now = v_timeGet();
            result->phaseMilliSeconds = ((c_ulong)(now.nanoseconds/1000000 * 1.618)) %
                result->msecsResolution;
            v_networkQueueUpdateNextWakeup(result, &hasChanged);
            assert(hasChanged);
        }
        result->threadWaiting = FALSE;
    } else {
        OS_REPORT(OS_ERROR,
                  "v_networkQueueNew",0,
                  "Failed to allocate network queue.");
    }
    return result;
}    
Beispiel #22
0
/**************************************************************
 * Public functions
 **************************************************************/
c_time
u_timeGet()
{
    return v_timeGet();
}
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;
}
Beispiel #24
0
void
v_leaseRenew(
    v_lease lease,
    v_duration* leaseDuration /* may be NULL */)
{
    c_iter observers = NULL;
    v_leaseManager observer;
    c_time newExpiryTime;
    c_equality cmp;

    if (lease != NULL) {
        assert(C_TYPECHECK(lease, v_lease));

        v_leaseLock(lease);
        /* Is a new lease duration provided, if so replace the current lease
         * duration with the new one
         */
        if(leaseDuration != NULL)
        {
            lease->duration = *leaseDuration;
        } /* else do nothing */
        /* Calculate the new expiry time */
        newExpiryTime = c_timeAdd(v_timeGet(), lease->duration);
        /* Is the new expiryTime earlier then the current expiryTime? */
        cmp = c_timeCompare(newExpiryTime, lease->expiryTime);
        /* Always replace the current expiry time with the new expiryTime */
        lease->expiryTime = newExpiryTime;
        /* If the new expiryTime is earlier then the previous expiryTime. Then
         * this means the observers must be notified so they can take the
         * earlier expiryTime into account
         */
        if (cmp == C_LT)
        {

            /* Collect all observers, so they can be notified of the lease change
             * Must do a seperate collect as the lease mutex is 'lower' then the
             * leaseManager mutex. So to prevent deadlock we can not directly notify
             * the lease manager as we walk the collection
             */
            if(lease->observers)
            {
                c_walk(lease->observers, v_leaseCollectObservers, &observers);
            }
            v_leaseUnlock(lease);
            if(observers)
            {
                observer = v_leaseManager(c_iterTakeFirst(observers));
                while (observer != NULL)
                {
                    v_leaseManagerNotify(
                        observer,
                        lease,
                        V_EVENT_LEASE_RENEWED);
                    c_free(observer);
                    observer = v_leaseManager(c_iterTakeFirst(observers));
                }
                c_iterFree(observers);
            }
        } else
        {
            /* No need to notify observers, the new expiryTime is not earlier
             * then what it was before.
             */
            v_leaseUnlock(lease);
        }
    }
}
void
d_nameSpacesRequestListenerAction(
    d_listener listener,
    d_message message)
{
    d_durability durability;
    d_admin admin;
    d_fellow fellow;
    d_publisher publisher;
    c_ulong i, count;
    d_nameSpaces ns;
    d_networkAddress addr;
    d_nameSpacesRequest request;
    c_bool added;
    c_iter nameSpaces;

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

    admin      = d_listenerGetAdmin(listener);
    durability = d_adminGetDurability(admin);
    addr       = d_networkAddressNew(message->senderAddress.systemId,
                                     message->senderAddress.localId,
                                     message->senderAddress.lifecycleId);
    fellow     = d_adminGetFellow(admin, addr);
    publisher  = d_adminGetPublisher(admin);

    d_printTimedEvent(durability, D_LEVEL_FINE,
            D_THREAD_NAMESPACES_REQUEST_LISTENER,
            "Received nameSpacesRequest from fellow %d.\n",
            message->senderAddress.systemId);

    /* Update nameSpaces list for listener */
    nameSpaces = updateNameSpaces(d_nameSpacesRequestListener(listener));

    if(!fellow){
        fellow = d_fellowNew(addr, message->senderState);
        d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());
        added = d_adminAddFellow(admin, fellow);

        if(added == FALSE){
            d_fellowFree(fellow);
            fellow = d_adminGetFellow(admin, addr);
            assert(fellow);
        } else {
            fellow = d_adminGetFellow(admin, addr);
            d_printTimedEvent(durability, D_LEVEL_FINE,
                D_THREAD_NAMESPACES_REQUEST_LISTENER,
                "Fellow %d unknown, added to administration and requesting nameSpaces.\n",
                message->senderAddress.systemId);
            request = d_nameSpacesRequestNew(admin);
            d_messageSetAddressee(d_message(request), addr);
            d_publisherNameSpacesRequestWrite(publisher, request, addr);
            d_nameSpacesRequestFree(request);
        }
    }
    d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());

    count = c_iterLength(nameSpaces);

    for(i=0; i<count; i++){
        ns = d_nameSpaces(c_iterObject(nameSpaces, i));
        d_messageInit(d_message(ns), admin);
        d_messageSetAddressee(d_message(ns), addr);
        d_publisherNameSpacesWrite(publisher, ns, addr);
    }
    cleanNameSpaces (nameSpaces);
    d_fellowFree(fellow);
    d_networkAddressFree(addr);

    return;
}
Beispiel #26
0
v_dataReaderSample
v_dataReaderSampleNew(
    v_dataReaderInstance instance,
    v_message message)
{
    v_dataReader dataReader;
    v_dataReaderSample sample;
    v_readerQos readerQos;
    v_index index;

    assert(instance != NULL);
    assert(C_TYPECHECK(message,v_message));

    index = v_index(instance->index);
    dataReader = v_dataReader(index->reader);
    readerQos = v_reader(dataReader)->qos;
    if (dataReader->cachedSample != NULL) {
        sample = dataReader->cachedSample;

/* Unfinished proto for cache size control
 * #define _SL_
 */
#ifdef _SL_
        dataReader->cachedSample = sample->prev;
        sample->prev = NULL;
        dataReader->cachedSampleCount--;
#else
        dataReader->cachedSample = NULL;
#endif
    } else {
        sample = v_dataReaderSample(c_extentCreate(dataReader->sampleExtent));
    }
    v_readerSample(sample)->instance = (c_voidp)instance;
    v_readerSample(sample)->viewSamples = NULL;
    if ((message->transactionId != 0) &&
        (v_reader(dataReader)->subQos->presentation.coherent_access))
    {
        v_readerSample(sample)->sampleState = L_TRANSACTION;
    } else {
        v_readerSample(sample)->sampleState = 0;
    }
#ifdef _NAT_
    sample->insertTime = v_timeGet();
#else
#define _INCORRECT_BUT_LOW_INSERT_LATENCY_
#ifdef _INCORRECT_BUT_LOW_INSERT_LATENCY_
    if (v_timeIsZero(v_reader(dataReader)->qos->latency.duration)) {
        sample->insertTime = v_timeGet();
    } else {
        sample->insertTime = message->allocTime;
    }
#else
    sample->insertTime = v_timeGet();
#endif
#endif
    if (readerQos->lifespan.used) { 
        v_lifespanSample(sample)->expiryTime = 
            c_timeAdd(sample->insertTime, readerQos->lifespan.duration);
    } else {
        v_lifespanSample(sample)->expiryTime = 
            c_timeAdd(sample->insertTime,
                      v_messageQos_getLifespanPeriod(message->qos));
    }
    sample->disposeCount = instance->disposeCount;
    sample->noWritersCount = instance->noWritersCount;
    sample->publicationHandle = message->writerGID;
    sample->readId = 0;
    sample->prev = NULL;
    assert(message);
    v_dataReaderSampleTemplate(sample)->message = c_keep(message);
    v_lifespanAdminInsert(v_dataReaderEntry(index->entry)->lifespanAdmin,
                          v_lifespanSample(sample));

    dataReader->notReadCount++;

    return sample;
}
Beispiel #27
0
c_bool
d_publisherDeleteDataWrite(
    d_publisher publisher,
    d_deleteData message,
    d_networkAddress addressee)
{
    c_bool result;
    u_result ur;
    int resendCount;
    c_bool terminate;
    d_durability durability;

    OS_UNUSED_ARG(addressee);
    result = FALSE;
    assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE);

    if(publisher){
        if(publisher->enabled == TRUE){
            terminate = FALSE;
            resendCount = 0;
            durability = d_adminGetDurability(publisher->admin);
            d_publisherInitMessage(publisher, d_message(message));
            d_message(message)->sequenceNumber = publisher->deleteDataNumber++;

            while((!result) && (!terminate)){
                ur = u_writerWrite(publisher->deleteDataWriter,
                                   message, v_timeGet(), U_INSTANCEHANDLE_NIL);

                if(ur == U_RESULT_OK){
                    result = TRUE;
                } else if(ur == U_RESULT_TIMEOUT) {
                    terminate = d_durabilityMustTerminate(durability);
                    resendCount++;

                    if(terminate){
                        d_printTimedEvent(durability, D_LEVEL_SEVERE, D_THREAD_UNSPECIFIED,
                            "Failed to resend d_deleteData message, because durability is terminating.\n");
                        OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0,
                            "Failed to send d_deleteData message, because durability is terminating.");
                    } else if((resendCount == 1) || ((resendCount % 5) == 0)){
                        d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_UNSPECIFIED,
                            "Already tried to resend d_deleteData message '%d' times.\n", resendCount);

                        if(resendCount != 1){
                            OS_REPORT_1(OS_WARNING, D_CONTEXT_DURABILITY, 0,
                                    "Already tried to resend d_deleteData message '%d' times.",
                                    resendCount);
                        }
                    }
                } else {
                    d_printTimedEvent(durability, D_LEVEL_SEVERE, D_THREAD_UNSPECIFIED,
                            "Write of d_deleteData message FAILED with result %d.\n", ur);
                    OS_REPORT_1(OS_ERROR, D_CONTEXT_DURABILITY, 0,
                            "Write of d_deleteData message FAILED with result %d.", ur);
                    d_durabilityTerminate(durability, TRUE);
                    terminate = d_durabilityMustTerminate(durability);
                }
            }
        }
    }
    return result;
}
Beispiel #28
0
c_bool
d_publisherStatusWrite(
    d_publisher publisher,
    d_status message,
    d_networkAddress addressee)
{
    c_bool result;
    u_result ur;
    int resendCount;
    c_bool terminate;
    d_durability durability;

    OS_UNUSED_ARG(addressee);
    result = FALSE;
    assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE);

    if(publisher){
        if(publisher->enabled == TRUE){
            terminate = FALSE;
            resendCount = 0;
            durability = d_adminGetDurability(publisher->admin);
            d_publisherInitMessage(publisher, d_message(message));
            d_message(message)->sequenceNumber = publisher->statusNumber++;

            while((!result) && (!terminate)){
                ur = u_writerWrite(publisher->statusWriter,
                                   message,
                                   v_timeGet(),
                                   U_INSTANCEHANDLE_NIL);

                if(ur == U_RESULT_OK){
                    result = TRUE;
                } else if(ur == U_RESULT_TIMEOUT) {
                    terminate = d_durabilityMustTerminate(durability);
                    if(!terminate && d_message(message)->senderState == D_STATE_TERMINATING){
                        /* ES 21 - okt - 2011:
                         * if durability is not yet terminating, but the message being written
                         * does indicate that termination of durability is imminent, then we have
                         * to prevent durability from constantly retrying in the case of a TIMEOUT
                         * of the datawriter. The standard timeout provided to the write will ensure
                         * the write is tried during the period of the timeout. But once that timeout is
                         * exceeded then it is fruitless to continue try to write the terminating message
                         * Without this specific code, durability will hang when terminating is caused
                         * by splice daemon terminating.
                         */
                        terminate = TRUE;
                    }
                    resendCount++;

                    if(terminate){
                        d_printTimedEvent(durability, D_LEVEL_SEVERE, D_THREAD_UNSPECIFIED,
                            "Failed to resend d_status message, because durability is terminating.\n");
                        OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0,
                            "Failed to send d_status message, because durability is terminating.");
                    }  else if((resendCount == 1) || ((resendCount % 5) == 0)){
                        d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_UNSPECIFIED,
                            "Already tried to resend d_status message '%d' times.\n", resendCount);

                        if(resendCount != 1){
                            OS_REPORT_1(OS_WARNING, D_CONTEXT_DURABILITY, 0,
                                    "Already tried to resend d_status message '%d' times.",
                                    resendCount);
                        }
                    }
                } else {
                    d_printTimedEvent(durability, D_LEVEL_SEVERE, D_THREAD_UNSPECIFIED,
                            "Write of d_status message FAILED with result %d.\n", ur);
                    OS_REPORT_1(OS_ERROR, D_CONTEXT_DURABILITY, 0,
                            "Write of d_status message FAILED with result %d.", ur);
                    d_durabilityTerminate(durability, TRUE);
                    terminate = d_durabilityMustTerminate(durability);
                }
            }
        }
    }
    return result;
}
Beispiel #29
0
c_bool
v_networkQueueWrite(
    v_networkQueue queue,
    v_message msg,
    v_networkReaderEntry entry,
    c_long sequenceNumber,
    v_gid sender,
    c_bool sendTo, /* for p2p writing */
    v_gid receiver)
{
    c_bool result = TRUE;
    c_bool wasEmpty;
    c_bool found;
    v_networkStatusMarker *currentMarkerPtr;
    v_networkStatusMarker currentMarker;
    v_networkStatusMarker marker;
    v_networkQueueSample newHolder;
    c_ulonglong msecsTime;
    c_ulonglong msecsResult;
    c_ulonglong msecsLeftOver;
    c_time sendBeforeNoTrunc;
    c_time sendBefore;
    c_time now;
    c_ulong priorityLookingFor;
    c_equality eq;
    c_bool newMarkerCreated = FALSE;
    c_bool sendNow = FALSE;
   
    V_MESSAGE_STAMP(msg,readerInsertTime); 

    c_mutexLock(&queue->mutex);

    /* numberOfSamplesArrived statistics */
    v_networkQueueStatisticsAdd(numberOfSamplesArrived,queue->statistics);

    if (queue->currentMsgCount == queue->maxMsgCount) {
        c_mutexUnlock(&queue->mutex);
        /* numberOfSamplesRejected stat */
        v_networkQueueStatisticsAdd(numberOfSamplesRejected,queue->statistics);
        return FALSE;
    }

    currentMarkerPtr = &(queue->firstStatusMarker);
    currentMarker = *currentMarkerPtr;

    if (queue->threadWaiting) {
        wasEmpty = !v_networkQueueHasExpiringData(queue);
    } else {
        wasEmpty = FALSE;
    }

    marker = NULL;
    found = FALSE;

    priorityLookingFor = v_messageQos_getTransportPriority(msg->qos);
    if (queue->periodic) {
        if (v_messageQos_isZeroLatency(msg->qos)) {
            sendBefore = C_TIME_ZERO;
            sendNow = TRUE;
        } else {
#ifdef _NAT_
            now = v_timeGet();
#else
            now = msg->allocTime;
#endif
            sendBeforeNoTrunc = c_timeAdd(now,
                                          v_messageQos_getLatencyPeriod(msg->qos));
            TIME_TO_MSEC(sendBeforeNoTrunc, msecsTime);
            msecsLeftOver = (c_ulonglong)((msecsTime - queue->phaseMilliSeconds) %
                                         queue->msecsResolution);
            msecsResult = (c_ulonglong)(msecsTime - msecsLeftOver);
            MSEC_TO_TIME(msecsResult, sendBefore);
        }
        while ((currentMarker != NULL) && (!found)) {
            eq = c_timeCompare(sendBefore, currentMarker->sendBefore);
            switch (eq) {
            case C_GT:
                currentMarkerPtr = &currentMarker->next;
                currentMarker = *currentMarkerPtr;
            break;
            case C_EQ:
                if (priorityLookingFor < currentMarker->priority) {
                    currentMarkerPtr = &currentMarker->next;
                    currentMarker = *currentMarkerPtr;
                } else {
                    found = TRUE;
                    if (priorityLookingFor == currentMarker->priority) {
                        marker = currentMarker;
                    }
                }
            break;
            case C_LT:
                found = TRUE;
            break;
            default:
                assert(FALSE);
            break;
            }
        }
    } else {
        if (currentMarker) {
        sendBefore = C_TIME_ZERO;
            if (c_timeIsZero(currentMarker->sendBefore)) {
                marker = currentMarker;
            }
        }
    }
    /* Insert after end of list */
    if (marker == NULL) {
        newMarkerCreated = TRUE;
        if (queue->freeStatusMarkers == NULL) {
            marker = v_networkStatusMarker(c_new(queue->statusMarkerType));
        } else {
            marker = queue->freeStatusMarkers;
            queue->freeStatusMarkers = marker->next;
        }

        if (marker != NULL) {
            marker->sendBefore = sendBefore;
            marker->priority = priorityLookingFor;
            marker->firstSample = NULL;
            marker->lastSample = NULL;
            marker->next = *currentMarkerPtr; /* no keep, transfer refCount */
            if (marker->next == NULL) {
                queue->lastStatusMarker = marker; /* no keep, not reference counted */
            }
            *currentMarkerPtr = marker; /* no keep, transfer refCount */
        } else {
            OS_REPORT(OS_ERROR,
                  "v_networkQueueWrite",0,
                  "Failed to send message.");
            c_mutexUnlock(&queue->mutex);
            return FALSE;
        }
    }
    V_MESSAGE_STAMP(msg,readerLookupTime); 
    assert(marker != NULL);
    if (queue->freeSamples == NULL) {
        newHolder = c_new(queue->sampleType);
    } else {
        newHolder = queue->freeSamples;
        queue->freeSamples = newHolder->next;
    }

    if (newHolder) {
        queue->currentMsgCount++;

        /* numberOfSamplesInserted & numberOfSamplesWaiting + stats*/
        v_networkQueueStatisticsAdd(numberOfSamplesInserted,queue->statistics);
        v_networkQueueStatisticsCounterInc(numberOfSamplesWaiting,queue->statistics);

        newHolder->message = c_keep(msg);
        newHolder->entry = c_keep(entry);
        newHolder->sequenceNumber = sequenceNumber;
        newHolder->sender = sender;
        newHolder->sendTo = sendTo;
        newHolder->receiver = receiver;

        if (marker->lastSample != NULL) {
            newHolder->next = v_networkQueueSample(marker->lastSample)->next; /* no keep, transfer refCount */
            v_networkQueueSample(marker->lastSample)->next = newHolder; /* no keep, transfer refCount */
        } else {
            newHolder->next = marker->firstSample; /* no keep, transfer refCount */
            marker->firstSample = newHolder; /* no keep, transfer refCount */
        }
        marker->lastSample = newHolder;


        /* Write done, wake up waiters if needed */
        if (wasEmpty && queue->threadWaiting) {
            if (sendNow || v_networkQueueHasExpiringData(queue)) {
                c_condBroadcast(&queue->cv);
            }
        }
    } else {
        OS_REPORT(OS_ERROR,
              "v_networkQueueWrite",0,
              "Failed to send message.");
        result = FALSE;
    }

    c_mutexUnlock(&queue->mutex);
    
    return result;
}
Beispiel #30
0
v_networkReaderWaitResult
v_networkQueueWait(
    v_networkQueue queue)
{
    v_networkReaderWaitResult result = V_WAITRESULT_NONE;
    c_syncResult syncResult;
    c_bool hasChanged;
    c_time interval;
    c_time minSleepTime = MIN_SLEEPTIME;
    c_equality eq;
    
    c_mutexLock(&queue->mutex);

    /* First update nextWakeup */
    v_networkQueueUpdateNextWakeup(queue, &hasChanged);
    if (hasChanged) {
        result |= V_WAITRESULT_TIMEOUT;
    }
    
    /* With the new nextWakeup, check if any data is expiring */
    if ((int)v_networkQueueHasExpiringData(queue)) {
        result |= V_WAITRESULT_MSGWAITING;
    }
    
    /* Also check if no request has been issued lately */
    if ((int)queue->triggered) {
        result |= V_WAITRESULT_TRIGGERED;
    }
    
    /* Now go to sleep if needed */
    while (result == V_WAITRESULT_NONE) {
        if (queue->periodic) {
            c_time org =  v_timeGet();
            interval = c_timeSub(queue->nextWakeup,org);
            eq = c_timeCompare(minSleepTime, interval);
            if (eq == C_LT) {
                queue->threadWaiting = TRUE;
                syncResult = c_condTimedWait(&queue->cv,
                                             &queue->mutex,
                                             interval);
                queue->threadWaiting = FALSE;
            } else {
                syncResult = SYNC_RESULT_TIMEOUT;
            }
            if (syncResult == SYNC_RESULT_TIMEOUT) {
                result |= V_WAITRESULT_TIMEOUT;
                queue->nextWakeup = c_timeAdd(queue->nextWakeup,
                                              queue->resolution);
            }
        } else {
            /* Wait infinitely if the queue is not periodic */
            queue->threadWaiting = TRUE;
            syncResult = c_condWait(&queue->cv, &queue->mutex);
            queue->threadWaiting = FALSE;
        }
        /* Test current status of queue */
        if ((int)queue->triggered) {
            result |= V_WAITRESULT_TRIGGERED;
        }
        if (v_networkQueueHasExpiringData(queue)) {
            result |= V_WAITRESULT_MSGWAITING;
        }
    }
    
    queue->triggered = 0;
    
    c_mutexUnlock(&queue->mutex);
    
    return result;
}