X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;ds=sidebyside;f=ao_write.c;h=fc65af60b3ca06735474e95c89de25387c1c9702;hb=41cb0352145fb8f95b6c14e69beb96efdd0e9b33;hp=fdae8eea542f97720f963f281bddd121cf5d0a38;hpb=79d6515d49cdb0a91ff7c4a599f2d63cb5678032;p=paraslash.git diff --git a/ao_write.c b/ao_write.c index fdae8eea..fc65af60 100644 --- a/ao_write.c +++ b/ao_write.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 Andre Noll + * Copyright (C) 2011-2014 Andre Noll * * 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);