/* Destroy a stream descriptor. */ void SNetStreamClose(snet_stream_desc_t *desc) { trace(__func__); assert(desc->refs == 0); SNetFifoDone(&desc->fifo); SNetDelete(desc); }
/* A record arriving via the loopback now leaves the feedback network. * Remove the detref structure and check for termination conditions. */ void SNetFeedbackLeave(snet_record_t *rec, landing_t *landing, fifo_t *detfifo) { snet_stack_t *stack; detref_t *detref, *first; trace(__func__); // record must have a stack of detrefs if ((stack = DATA_REC(rec, detref)) == NULL) { SNetUtilDebugFatal("[%s]: missing stack.", __func__); } // stack must have at least one detref if ((detref = SNetStackPop(stack)) == NULL) { SNetUtilDebugFatal("[%s]: empty stack.", __func__); } if (SNetStackIsEmpty(stack)) { SNetStackDestroy(stack); DATA_REC(rec, detref) = NULL; } // detref must refer to this DetLeave node if (detref->leave != landing) { SNetUtilDebugFatal("[%s]: leave %p != landing %p.", __func__, detref->leave, landing); } // reference counter must be at least two if (detref->refcount < 2) { SNetUtilDebugFatal("[%s]: refcnt %d < 1.", __func__, detref->refcount); } // decrease reference count if (DETREF_DECR(detref) == 1) { DETREF_DECR(detref); } assert(detref->refcount >= 0); // pop detrefs in sequence which have no more records in the loopback left. while ((first = SNetFifoPeekFirst(detfifo)) != NULL) { // stop processing if more records to come for this sequence counter if (first->refcount > 0) { break; } SNetFifoGet(detfifo); SNetFifoDone(&first->recfifo); SNetDelete(first); } }
/* Check if there are any records in the dripback loop left. */ static bool DripBackCheckBusy(landing_dripback2_t *db2) { detref_t *first; /* check if dripback loop is still active */ while ((first = SNetFifoPeekFirst(&db2->detfifo)) != NULL) { BAR(); if (first->refcount > 0) { break; } SNetFifoGet(&db2->detfifo); SNetFifoDone(&first->recfifo); SNetDelete(first); } return first ? true : false; }
/* Check if there are any records in the feedback loop left. */ static void FeedbackCheckBusy(landing_feedback3_t *fb3) { detref_t *first; /* check if feedback loop is still active */ while ((first = SNetFifoPeekFirst(&fb3->detfifo)) != NULL) { if (first->refcount > 0) { break; } SNetFifoGet(&fb3->detfifo); SNetFifoDone(&first->recfifo); SNetDelete(first); } if (first == NULL && fb3->terminate == FeedbackDraining) { fb3->terminate = FeedbackTerminating; } }