removing ACKd messages with noidx optimisation can fail if samples have been written after matching multiple readers but before the first ACK arrives

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2018-05-21 17:25:46 +08:00
parent 6d48d692ba
commit 33c89f0d47

View file

@ -676,10 +676,23 @@ static unsigned whc_remove_acked_messages_noidx (struct whc *whc, seqno_t max_dr
/* Drop everything up to and including max_drop_seq, or absent that one, /* Drop everything up to and including max_drop_seq, or absent that one,
the highest available sequence number (which then must be less) */ the highest available sequence number (which then must be less) */
if ((whcn = whc_findseq (whc, max_drop_seq)) == NULL) if ((whcn = whc_findseq (whc, max_drop_seq)) == NULL)
{
if (max_drop_seq < intv->min)
{
/* at startup, whc->max_drop_seq = 0 and reader states have max ack'd seq taken from wr->seq;
so if multiple readers are matched and the writer runs ahead of the readers, for the first
ack, whc->max_drop_seq < max_drop_seq = MIN(readers max ack) < intv->min */
if (max_drop_seq > whc->max_drop_seq)
whc->max_drop_seq = max_drop_seq;
*deferred_free_list = NULL;
return 0;
}
else
{ {
whcn = whc->maxseq_node; whcn = whc->maxseq_node;
assert (whcn->seq < max_drop_seq); assert (whcn->seq < max_drop_seq);
} }
}
*deferred_free_list = intv->first; *deferred_free_list = intv->first;
ndropped = (unsigned) (whcn->seq - intv->min + 1); ndropped = (unsigned) (whcn->seq - intv->min + 1);