memblockq: remove internal "missing" state variable
authorPierre Ossman <ossman@cendio.se>
Thu, 19 May 2016 13:54:08 +0000 (15:54 +0200)
committerArun Raghavan <arun@arunraghavan.net>
Fri, 22 Jul 2016 11:00:25 +0000 (16:30 +0530)
It was a very confusing state variable that required a lot of
fiddling. It was also redundant in that it can be computed from
the other variables, removing any risk of it getting out of sync.
In the same spirit, make sure "requested" also always contains a
sane value, even though it may not be used by every caller.

src/pulsecore/memblockq.c

index f660ffa..b1b4fde 100644 (file)
@@ -53,7 +53,7 @@ struct pa_memblockq {
     bool in_prebuf;
     pa_memchunk silence;
     pa_mcalign *mcalign;
-    int64_t missing, requested;
+    size_t requested;
     char *name;
     pa_sample_spec sample_spec;
 };
@@ -251,10 +251,12 @@ static void write_index_changed(pa_memblockq *bq, int64_t old_write_index, bool
 
     delta = bq->write_index - old_write_index;
 
-    if (account)
-        bq->requested -= delta;
-    else
-        bq->missing -= delta;
+    if (account) {
+        if (delta > (int64_t)bq->requested)
+            bq->requested = 0;
+        else if (delta > 0)
+            bq->requested -= delta;
+    }
 
 #ifdef MEMBLOCKQ_DEBUG
      pa_log_debug("[%s] pushed/seeked %lli: requested counter at %lli, account=%i", bq->name, (long long) delta, (long long) bq->requested, account);
@@ -262,15 +264,14 @@ static void write_index_changed(pa_memblockq *bq, int64_t old_write_index, bool
 }
 
 static void read_index_changed(pa_memblockq *bq, int64_t old_read_index) {
+#ifdef MEMBLOCKQ_DEBUG
     int64_t delta;
 
     pa_assert(bq);
 
     delta = bq->read_index - old_read_index;
-    bq->missing += delta;
 
-#ifdef MEMBLOCKQ_DEBUG
-    pa_log_debug("[%s] popped %lli: missing counter at %lli", bq->name, (long long) delta, (long long) bq->missing);
+    pa_log_debug("[%s] popped %lli", bq->name, (long long) delta);
 #endif
 }
 
@@ -829,31 +830,37 @@ size_t pa_memblockq_get_prebuf(pa_memblockq *bq) {
 }
 
 size_t pa_memblockq_pop_missing(pa_memblockq *bq) {
-    size_t l;
+    int64_t length;
+    size_t missing;
 
     pa_assert(bq);
 
-#ifdef MEMBLOCKQ_DEBUG
-    pa_log_debug("[%s] pop: %lli", bq->name, (long long) bq->missing);
-#endif
+    /* Note that write_index might be before read_index, which means
+     * that we should ask for extra data to catch up. This also means
+     * that we cannot call pa_memblockq_length() as it doesn't return
+     * negative values. */
 
-    if (bq->missing <= 0)
+    length = (bq->write_index - bq->read_index) + bq->requested;
+
+    if (length > (int64_t)bq->tlength)
         return 0;
 
-    if (((size_t) bq->missing < bq->minreq) &&
-        !pa_memblockq_prebuf_active(bq))
+    missing = (int64_t)bq->tlength - length;
+
+    if (missing == 0)
         return 0;
 
-    l = (size_t) bq->missing;
+    if ((missing < bq->minreq) &&
+        !pa_memblockq_prebuf_active(bq))
+        return 0;
 
-    bq->requested += bq->missing;
-    bq->missing = 0;
+    bq->requested += missing;
 
 #ifdef MEMBLOCKQ_DEBUG
-    pa_log_debug("[%s] sent %lli: request counter is at %lli", bq->name, (long long) l, (long long) bq->requested);
+    pa_log_debug("[%s] sent %lli: request counter is at %lli", bq->name, (long long) missing, (long long) bq->requested);
 #endif
 
-    return l;
+    return missing;
 }
 
 void pa_memblockq_set_maxlength(pa_memblockq *bq, size_t maxlength) {
@@ -869,13 +876,11 @@ void pa_memblockq_set_maxlength(pa_memblockq *bq, size_t maxlength) {
 }
 
 void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {
-    size_t old_tlength;
     pa_assert(bq);
 
     if (tlength <= 0 || tlength == (size_t) -1)
         tlength = bq->maxlength;
 
-    old_tlength = bq->tlength;
     bq->tlength = ((tlength+bq->base-1)/bq->base)*bq->base;
 
     if (bq->tlength > bq->maxlength)
@@ -886,8 +891,6 @@ void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {
 
     if (bq->prebuf > bq->tlength+bq->base-bq->minreq)
         pa_memblockq_set_prebuf(bq, bq->tlength+bq->base-bq->minreq);
-
-    bq->missing += (int64_t) bq->tlength - (int64_t) old_tlength;
 }
 
 void pa_memblockq_set_minreq(pa_memblockq *bq, size_t minreq) {