Hi there,
After a few email on the mailing list, I found the bug. In fact, when FEC blocks are done they are never removed from the freeBlocks leading at the end of a shortage of freeBlocks causing the deadlock.
So IFAIK, the recent releases are affected when activating the FEC.
As the releasing code was almost existing, I've been making it generic.
I don't know if it's the cleaner way to solve it but at least, that solved my deadlock issue.
diff --git a/receivedata.c b/receivedata.c index 3f213d5..692260d 100644 --- a/receivedata.c +++ b/receivedata.c @@ -135,6 +135,8 @@ struct clientState { #endif };
+static void freeFecBlocks(struct clientState *clst, slice_t slice); + static void printMissedBlockMap(struct clientState *clst, slice_t slice) { int i, first=1; @@ -460,7 +462,11 @@ static void cleanupSlices(struct clientState *clst, unsigned int doneState) clst->slices[pos].sliceNo, pos, &clst->slices[pos]); #endif pc_produce(clst->free_slices_pc, 1); - + + if (doneState == SLICE_FEC_DONE) { + freeFecBlocks(clst,slice); + } + /* if at end, exit this thread */ if(!bytes) { clst->endReached = 2; @@ -586,6 +592,23 @@ static void fec_decode_one_stripe(struct clientState *clst, }
+static void freeFecBlocks(struct clientState *clst, slice_t slice) { + int stripes = slice->fec_stripes; + struct fec_desc *fec_descs = slice->fec_descs; + int stripe; + for(stripe=0; stripe<stripes; stripe++) { + int i; + assert(slice->missing_data_blocks[stripe] >= + slice->fec_blocks[stripe]); + for(i=0; i<slice->fec_blocks[stripe]; i++) { + if (fec_descs[stripe+i*stripes].adr != NULL) { + freeBlockSpace(clst,fec_descs[stripe+i*stripes].adr); + fec_descs[stripe+i*stripes].adr=0; + } + } + } +} + static THREAD_RETURN fecMain(void *args0) { struct clientState *clst = (struct clientState *) args0; @@ -627,15 +650,7 @@ static THREAD_RETURN fecMain(void *args0) }
slice->state = SLICE_FEC_DONE; - for(stripe=0; stripe<stripes; stripe++) { - int i; - assert(slice->missing_data_blocks[stripe] >= - slice->fec_blocks[stripe]); - for(i=0; i<slice->fec_blocks[stripe]; i++) { - freeBlockSpace(clst,fec_descs[stripe+i*stripes].adr); - fec_descs[stripe+i*stripes].adr=0; - } - } + freeFecBlocks(clst,slice); } else if(slice->state == SLICE_DONE) { slice->state = SLICE_FEC_DONE; }