/*
- * 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.
*/
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);
}
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);
ao_write_cmdline_parser_init(&dummy);
w->close = aow_close;
w->pre_select = aow_pre_select;
- w->new_post_select = aow_post_select;
- w->post_select = NULL;
+ 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 */