]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - ao_write.c
ao_write: Enforce a 20ms timeout.
[paraslash.git] / ao_write.c
index 9d204ff3b5220afebbf29efd14d3721411c60b17..fc65af60b3ca06735474e95c89de25387c1c9702 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2011-2014 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -48,10 +48,26 @@ static void aow_close(struct writer_node *wn)
 static void aow_pre_select(struct sched *s, struct task *t)
 {
        struct writer_node *wn = container_of(t, struct writer_node, task);
-       int ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF);
+       struct private_aow_data *pawd = wn->private_data;
+       int ret;
 
-       if (ret == 0)
-               return;
+       if (pawd)
+               pthread_mutex_lock(&pawd->mutex);
+       ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF);
+       if (pawd)
+               pthread_mutex_unlock(&pawd->mutex);
+
+       if (ret == 0) {
+               /*
+                * Even though the node status is zero, we might have data
+                * available, but the output buffer is full. If we don't set a
+                * timeout here, we are woken up only if new data arrives,
+                * which might be too late and result in a buffer underrun in
+                * the playing thread. To avoid this we never sleep longer than
+                * the (default) buffer time.
+                */
+               return sched_request_timeout_ms(20, s);
+       }
        sched_min_delay(s);
 }
 
@@ -223,7 +239,9 @@ __noreturn static void *aow_play(void *priv)
                ret = -E_AO_PLAY;
                if (ao_play(pawd->dev, data, bytes) == 0) /* failure */
                        goto out;
+               pthread_mutex_lock(&pawd->mutex);
                btr_consume(btrn, bytes);
+               pthread_mutex_unlock(&pawd->mutex);
        }
 unlock:
        pthread_mutex_unlock(&pawd->mutex);
@@ -371,9 +389,7 @@ void ao_write_init(struct writer *w)
        w->post_select = aow_post_select;
        w->parse_config_or_die = aow_parse_config_or_die;
        w->free_config = aow_free_config;
-       w->help = (struct ggo_help) {
-               .short_help = ao_write_args_info_help,
-       };
+       w->help = (struct ggo_help)DEFINE_GGO_HELP(ao_write);
        /* create detailed help containing all supported drivers/options */
        for (i = 0; ao_write_args_info_detailed_help[i]; i++)
                ; /* nothing */