c_iter
v_deadLineInstanceListCheckDeadlineMissed(
    v_deadLineInstanceList list,
    v_duration deadlineTime,
    c_time now)
{
    c_time expiryTime;
    v_instance listItem;
    c_iter missed;

    assert(C_TYPECHECK(list,v_deadLineInstanceList));

    missed = NULL;
    if (v_instanceAlone(v_instance(list))) { /* list is empty */
        assert (list->deadlineLease != NULL);
        v_leaseManagerDeregister(list->leaseManager, list->deadlineLease);
        c_free(list->deadlineLease);
        list->deadlineLease = NULL;
    } else {
        listItem = v_instance(list)->prev;
        expiryTime = c_timeSub(now, deadlineTime);
        while ((listItem != NULL) &&
                (v_objectKind(listItem) != K_DEADLINEINSTANCE)  &&
                (c_timeCompare(expiryTime, listItem->lastCheckTime) != C_LT)) {
            missed = c_iterInsert(missed, listItem);
            listItem->lastCheckTime = now;
            listItem = listItem->prev;
        }
        /* determine next wake-up time */
        if (v_objectKind(listItem) == K_DEADLINEINSTANCE) {
            /* listItem is the deadline list itself, so if there
             * were instances all instances have been missed. Just
             * set the new check to be in 'deadlineTime'.
             */
            expiryTime = deadlineTime;
        } else {
            /*
             * The new lease duration can be calculated:
             * lastCheckTime + deadlineTime = next expiry time
             * next expiry time - now = lease duration
             */
            expiryTime = c_timeAdd(listItem->lastCheckTime, deadlineTime);
            expiryTime = c_timeSub(expiryTime, now);
            v_leaseRenew(list->deadlineLease, expiryTime);
        }
    }
    return missed;
}
Exemple #2
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);
}
Exemple #3
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;
}
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;
}
Exemple #5
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;
}    
/**************************************************************
 * Main / notify fnctions
 **************************************************************/
void
v_leaseManagerMain(
    v_leaseManager _this)
{
    v_leaseAction leaseAction;
    c_time waitTime = C_TIME_ZERO;
    c_time expTime;
    v_duration duration;
    struct collectExpiredArg arg;
    c_syncResult waitResult = SYNC_RESULT_SUCCESS;

    assert(_this != NULL);
    assert(C_TYPECHECK(_this, v_leaseManager));

    c_mutexLock(&_this->mutex);
    /* initialize the current time once before the loop */
    arg.now = v_timeGet();
    while (_this->quit == FALSE) {
        if (_this->firstLeaseToExpire != NULL) {
            v_leaseGetExpiryAndDuration(_this->firstLeaseToExpire->lease, &expTime, &duration);
            if (c_timeCompare(expTime, C_TIME_INFINITE) != C_EQ) {
                waitTime = c_timeSub(expTime, arg.now);
                if (c_timeCompare(waitTime, C_TIME_ZERO) == C_GT) {
                    waitResult = c_condTimedWait(&_this->cond, &_this->mutex, waitTime);
                } else {
                    /* If the duration specified with the lease is C_TIME_ZERO,
                     * it is expected that the expiryTime lies in the past, so
                     * only warn if an actual duration was specified. */
                    if(c_timeCompare(duration, C_TIME_ZERO) != C_EQ){
                        OS_REPORT(OS_WARNING, "v_leaseManager", 0,
                            "The wait time has become negative! This means "
                            "that the leaseManager could not wake up in time to "
                            "evaluate the lease expiry statusses. This could be "
                            "due to scheduling problems or clock alignment issues on "
                            "multi core machines. The lease manager will continue to "
                            "function normal after this though.");
                    }
                }
            } else {
                /* The shortest expiry time is from a lease with an infinite duration. So
                 * wait indefinately
                 */
                waitResult = c_condWait(&_this->cond, &_this->mutex);
            }
        } else {
            /* no leases registered, so wait until the first one is registered */
            waitResult = c_condWait(&_this->cond, &_this->mutex);
        }

        if (waitResult == SYNC_RESULT_FAIL)
        {
            OS_REPORT(OS_CRITICAL, "v_leaseManagerMain", 0,
                      "c_condTimedWait / c_condWait failed - thread will terminate");
            break;
        }

        /**
         * First walk through the collection of leases and record all
         * expired leases in an iterator. We cannot remove expired leases
         * while walking through the set, since it interferes with the
         * walk.
         * Any lease with a repeat bool to TRUE  will automatically be renewed
         * while collecting all the leases.
         */
        arg.expiredLeases = NULL;
        arg.firstLeaseToExpire = NULL;
        arg.now = v_timeGet();
        c_setWalk(_this->leases, collectExpired, &arg);

        c_free(_this->firstLeaseToExpire);
        _this->firstLeaseToExpire = arg.firstLeaseToExpire;/* takes over ref count from arg object */
        c_mutexUnlock(&_this->mutex);

        leaseAction = v_leaseAction(c_iterTakeFirst(arg.expiredLeases));
        while (leaseAction != NULL) {
            if(!leaseAction->repeat)
            {
                v_leaseManagerDeregister(_this, leaseAction->lease);
            }
            v_leaseManagerProcessLeaseAction(_this, leaseAction, arg.now);
            c_free(leaseAction);
            leaseAction = v_leaseAction(c_iterTakeFirst(arg.expiredLeases));
        }
        c_iterFree(arg.expiredLeases);
        c_mutexLock(&_this->mutex);
    }
    _this->quit = FALSE; /* for a next time */
    c_mutexUnlock(&_this->mutex);
}