X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=oss_write.c;h=5b910742e3ada1ac084bac89183d3b8e75d03852;hb=5414dfd4356e63634f1a4e94382d14e200759d18;hp=d547acf7422e2437a2af0d74f706d477bea8c309;hpb=d1e6b28f66e243516d01916f9125baee75dd98d6;p=paraslash.git diff --git a/oss_write.c b/oss_write.c index d547acf7..5b910742 100644 --- a/oss_write.c +++ b/oss_write.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014 Andre Noll + * Copyright (C) 2009-2014 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -31,6 +31,29 @@ struct private_oss_write_data { int bytes_per_frame; }; +/* + * We keep one bit of static storage to make sure only one instance of the oss + * writer is running at any given time. + */ +static bool sound_device_busy; + +static bool sound_device_is_busy(void) +{ + return sound_device_busy; +} + +static void set_sound_device_busy(void) +{ + assert(!sound_device_busy); + sound_device_busy = true; +} + +static void set_sound_device_idle(void) +{ + assert(sound_device_busy); + sound_device_busy = false; +} + static int get_oss_format(enum sample_format sf) { switch (sf) { @@ -44,13 +67,13 @@ static int get_oss_format(enum sample_format sf) } } -static void oss_pre_select(struct sched *s, struct task *t) +static void oss_pre_select(struct sched *s, void *context) { - struct writer_node *wn = container_of(t, struct writer_node, task); + struct writer_node *wn = context; struct private_oss_write_data *powd = wn->private_data; int ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF); - if (ret == 0) + if (ret == 0 || (sound_device_is_busy() && !powd)) return; if (ret < 0 || !powd) return sched_min_delay(s); @@ -65,6 +88,7 @@ static void oss_close(struct writer_node *wn) return; close(powd->fd); free(powd); + set_sound_device_idle(); } /* @@ -157,17 +181,16 @@ err_free: return ret; } -static int oss_post_select(__a_unused struct sched *s, - struct task *t) +static int oss_post_select(__a_unused struct sched *s, void *context) { - struct writer_node *wn = container_of(t, struct writer_node, task); + struct writer_node *wn = context; struct private_oss_write_data *powd = wn->private_data; struct btr_node *btrn = wn->btrn; size_t frames, bytes; int ret; char *data; - ret = task_get_notification(t); + ret = task_get_notification(wn->task); if (ret < 0) goto out; ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF); @@ -175,12 +198,16 @@ static int oss_post_select(__a_unused struct sched *s, goto out; if (!powd) { int32_t rate, ch, format; + + if (sound_device_is_busy()) + return 0; get_btr_sample_rate(btrn, &rate); get_btr_channels(btrn, &ch); get_btr_sample_format(btrn, &format); ret = oss_init(wn, rate, ch, format); if (ret < 0) goto out; + set_sound_device_busy(); return 0; } btr_merge(btrn, wn->min_iqs);