Beispiel #1
0
c_bool
v_networkQueueTakeFirst(
    v_networkQueue queue,
    v_message *message,
    v_networkReaderEntry *entry,
    c_ulong *sequenceNumber,
    v_gid *sender,
    c_bool *sendTo, /* for p2p writing */
    v_gid *receiver,
    c_time *sendBefore,
    c_ulong *priority,
    c_bool *more)
{
    c_bool result = FALSE;
    v_networkStatusMarker currentMarker;
    v_networkQueueSample sample;

    *more = FALSE;
    
    c_mutexLock(&queue->mutex);

    currentMarker = queue->firstStatusMarker;
    /* Note: the current design expects that this function has been preceded
     *       by a NetworkReaderWait. Therefore, the currentMarker should never
     *       be NULL. */

    if (currentMarker != NULL) {
        sample = currentMarker->firstSample;
        assert(sample != NULL);
        result = TRUE;
        
        V_MESSAGE_STAMP(sample->message,readerDataAvailableTime); 

        /* Copy values */
        *message = sample->message; /* no keep, transfer refCount */
        sample->message = NULL; /* clean reference because of  refCount transfer */
        *entry = sample->entry; /* no keep, transfer refCount */
        sample->entry = NULL; /* clean reference because of refCount transfer */
        *sequenceNumber = sample->sequenceNumber;
        *sender = sample->sender;
        *sendTo = sample->sendTo;
        *receiver = sample->receiver;
        *sendBefore = currentMarker->sendBefore;
        *priority = currentMarker->priority;
        
        /* Remove and free holder */
        queue->currentMsgCount--;

        /* numberOfSamplesTaken+ & numberOfSamplesWaiting- stats */
        v_networkQueueStatisticsAdd(numberOfSamplesTaken,queue->statistics);
        v_networkQueueStatisticsCounterDec(numberOfSamplesWaiting,queue->statistics);


        currentMarker->firstSample = sample->next; /* no keep, transfer refCount */
        sample->next = queue->freeSamples;
        queue->freeSamples = sample;
        if (currentMarker->firstSample == NULL) {
            queue->firstStatusMarker = currentMarker->next; /* no keep, transfer refCount */
            currentMarker->next = queue->freeStatusMarkers;
            queue->freeStatusMarkers = currentMarker;
            if (queue->firstStatusMarker == NULL) {
                queue->lastStatusMarker = NULL;
            }
        }
        *more = (queue->firstStatusMarker != NULL);
    } else {
        *message = NULL;
        *entry = NULL;
        *more = FALSE;
    }
    c_mutexUnlock(&queue->mutex);
    
    return result;
}
Beispiel #2
0
void
v_subscriberLockShares(
    v_subscriber _this)
{
    c_mutexLock(&_this->sharesMutex);
}
Beispiel #3
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));
            if (marker == NULL) {
                OS_REPORT(OS_ERROR,
                          "v_networkQueueWrite",0,
                          "Failed to allocate v_networkStatusMarker object.");
                c_mutexUnlock(&queue->mutex);
                return FALSE;
            }
        } else {
            marker = queue->freeStatusMarkers;
            queue->freeStatusMarkers = marker->next;
        }

        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 */
    }
    V_MESSAGE_STAMP(msg,readerLookupTime); 
    assert(marker != NULL);
    if (queue->freeSamples == NULL) {
        newHolder = c_new(queue->sampleType);
        if (newHolder == NULL) {
            OS_REPORT(OS_ERROR,
                      "v_networkQueueWrite",0,
                      "Failed to allocate v_networkQueueSample object.");
            result = FALSE;
            c_mutexUnlock(&queue->mutex);
            return result;
        }
    } else {
        newHolder = queue->freeSamples;
        queue->freeSamples = newHolder->next;
    }

    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);
        }
    }

    c_mutexUnlock(&queue->mutex);
    
    return result;
}
Beispiel #4
0
void
v_lockShares(
    v_kernel kernel)
{
    c_mutexLock(&kernel->sharesMutex);
}