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; }
void v_subscriberLockShares( v_subscriber _this) { c_mutexLock(&_this->sharesMutex); }
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 = ¤tMarker->next; currentMarker = *currentMarkerPtr; break; case C_EQ: if (priorityLookingFor < currentMarker->priority) { currentMarkerPtr = ¤tMarker->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; }
void v_lockShares( v_kernel kernel) { c_mutexLock(&kernel->sharesMutex); }