From: Takashi Iwai <tiwai@suse.de>
To: Anders Torger <torger@ludd.luth.se>
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: Why do I get broken pipe on write to a pcm in state PREPARED?
Date: Thu, 12 Sep 2002 17:56:42 +0200 [thread overview]
Message-ID: <s5h1y7zp5fp.wl@alsa2.suse.de> (raw)
In-Reply-To: <200209121148.g8CBmv020843@d1o87.telia.com>
[-- Attachment #1: Type: text/plain, Size: 1773 bytes --]
At Thu, 12 Sep 2002 13:48:56 +0200,
Anders Torger wrote:
>
(...snipped the analogy of pipes...)
>
> Well, I have the same opinion, I'd just like to give another example
> (actually the same all over again, but I want to make it obvious). For
> a socket or a pipe, if noone reads from the other end, it will block
> forever. Thus, a buggy program will dead-lock. I think this example
> fits logically the case of writing to the sound-card but no-one starts
> it. It should then block forever.
agreed, although the alsa is already apart from the standard device
operations (unlike normal devices, alsa needs an explicit set-up
before read/write).
> The problem I have is that I do not see the use of generating a broken
> pipe in this situation, the only scenario I can come up with is "oh, I
> got a broken pipe, I must have forgotten to start the pcm, so I do it
> and try writing again". But that scenario is highly unlikely to occur
> in a program, and if it does, I would call it bad programming.
>
> For the blocking case, however, there is a use, that of having multiple
> threads (or forked processes). In my case I have a input thread and and
> output thread, and the sound-card is started from the input thread,
> after the output buffer has been readily filled with data. Not that it
> is hard to change my program to do like ALSA wants it, but I think the
> behaviour is wrong, it is not what one would expect.
we can see this problem from a different angle: on the current
scheme, you cannot block writing if the stream is not running.
writing more in the prepare state will always return an error
immediately.
btw, the attached patch is a quick and untested hack to change the
behavior as you wish :)
please give a try.
ciao,
Takashi
[-- Attachment #2: pcm-poll-fix.dif --]
[-- Type: application/octet-stream, Size: 3293 bytes --]
Index: alsa-kernel/core/pcm_lib.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/pcm_lib.c,v
retrieving revision 1.19
diff -u -r1.19 pcm_lib.c
--- alsa-kernel/core/pcm_lib.c 12 Aug 2002 09:45:01 -0000 1.19
+++ alsa-kernel/core/pcm_lib.c 12 Sep 2002 11:26:57 -0000
@@ -1842,14 +1842,9 @@
if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream);
avail = snd_pcm_playback_avail(runtime);
- if (runtime->status->state == SNDRV_PCM_STATE_PAUSED ||
- runtime->status->state == SNDRV_PCM_STATE_PREPARED) {
- if (avail < runtime->xfer_align) {
- err = -EPIPE;
- goto _end_unlock;
- }
- } else if (((avail < runtime->control->avail_min && size > avail) ||
- (size >= runtime->xfer_align && avail < runtime->xfer_align))) {
+ if (((runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
+ avail < runtime->control->avail_min && size > avail) ||
+ (size >= runtime->xfer_align && avail < runtime->xfer_align))) {
wait_queue_t wait;
enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state;
if (nonblock) {
@@ -1860,32 +1855,38 @@
init_waitqueue_entry(&wait, current);
add_wait_queue(&runtime->sleep, &wait);
while (1) {
+ state = READY;
set_current_state(TASK_INTERRUPTIBLE);
if (signal_pending(current)) {
state = SIGNALED;
break;
}
spin_unlock_irq(&runtime->lock);
- if (schedule_timeout(10 * HZ) == 0) {
- spin_lock_irq(&runtime->lock);
- state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
- break;
- }
+ if (schedule_timeout(10 * HZ) == 0)
+ state = EXPIRED;
spin_lock_irq(&runtime->lock);
switch (runtime->status->state) {
- case SNDRV_PCM_STATE_XRUN:
- state = ERROR;
- goto _end_loop;
case SNDRV_PCM_STATE_SUSPENDED:
state = SUSPENDED;
goto _end_loop;
- default:
- break;
- }
- avail = snd_pcm_playback_avail(runtime);
- if (avail >= runtime->control->avail_min) {
+ case SNDRV_PCM_STATE_PREPARED:
+ case SNDRV_PCM_STATE_PAUSED:
state = READY;
+ avail = snd_pcm_playback_avail(runtime);
+ if (avail >= runtime->xfer_align)
+ goto _end_loop;
break;
+ case SNDRV_PCM_STATE_RUNNING:
+ if (state != READY)
+ goto _end_loop;
+ avail = snd_pcm_playback_avail(runtime);
+ if (avail >= runtime->control->avail_min)
+ goto _end_loop;
+ break;
+ case SNDRV_PCM_STATE_XRUN:
+ default:
+ state = ERROR;
+ goto _end_loop;
}
}
_end_loop:
Index: alsa-kernel/core/pcm_native.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/pcm_native.c,v
retrieving revision 1.22
diff -u -r1.22 pcm_native.c
--- alsa-kernel/core/pcm_native.c 26 Aug 2002 10:00:17 -0000 1.22
+++ alsa-kernel/core/pcm_native.c 12 Sep 2002 11:01:14 -0000
@@ -2437,11 +2437,13 @@
mask = 0;
break;
case SNDRV_PCM_STATE_PREPARED:
+ case SNDRV_PCM_STATE_PAUSED:
if (avail > 0) {
mask = POLLOUT | POLLWRNORM;
break;
}
- /* Fall through */
+ mask = 0;
+ break;
default:
mask = POLLOUT | POLLWRNORM | POLLERR;
break;
next prev parent reply other threads:[~2002-09-12 15:56 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Pine.LNX.4.33.0209112103010.607-100000@pnote.perex-int.cz>
2002-09-11 19:26 ` Why do I get broken pipe on write to a pcm in state PREPARED? Anders Torger
2002-09-11 20:14 ` Paul Davis
2002-09-12 11:13 ` Takashi Iwai
2002-09-12 11:48 ` Anders Torger
2002-09-12 15:56 ` Takashi Iwai [this message]
2002-09-12 16:14 ` Anders Torger
2002-09-12 20:02 ` Tim Goetze
2002-09-13 9:41 ` Jaroslav Kysela
2002-09-13 10:43 ` Takashi Iwai
2002-09-13 11:45 ` Tim Goetze
2002-09-13 12:37 ` Takashi Iwai
2002-09-15 17:56 ` Why do I get broken pipe on write to a pcm in statePREPARED? Abramo Bagnara
2002-09-16 10:46 ` Takashi Iwai
2002-09-16 13:18 ` Tim Goetze
2002-09-16 14:31 ` Takashi Iwai
2002-09-16 19:31 ` Abramo Bagnara
2002-09-16 19:49 ` Tim Goetze
2002-09-16 20:14 ` Anders Torger
2002-09-17 8:12 ` Abramo Bagnara
2002-09-17 9:03 ` Anders Torger
2002-09-17 13:04 ` Paul Davis
2002-09-17 9:05 ` Clemens Ladisch
2002-09-17 10:09 ` Anders Torger
2002-09-17 11:09 ` Takashi Iwai
2002-09-17 11:55 ` tomasz motylewski
2002-09-17 12:52 ` Takashi Iwai
2002-09-17 13:01 ` Anders Torger
2002-09-17 14:40 ` Clemens Ladisch
2002-09-18 19:57 ` Anders Torger
2002-10-04 8:14 ` Anders Torger
2002-10-04 12:58 ` Takashi Iwai
2002-10-04 18:04 ` Abramo Bagnara
2002-10-07 10:15 ` Takashi Iwai
2002-10-07 12:07 ` Abramo Bagnara
2002-10-07 13:19 ` Anders Torger
2002-10-07 17:46 ` Abramo Bagnara
2002-10-08 9:54 ` Takashi Iwai
2002-10-07 13:57 ` Tim Goetze
2002-10-09 18:13 ` Jack O'Quin
2002-09-17 13:03 ` Paul Davis
2002-10-15 15:49 ` multiple devices/ possible bug in aplay or somewhere else? Guilhem Tardy
2002-10-15 16:14 ` Jaroslav Kysela
2002-10-15 17:05 ` Guilhem Tardy
2002-09-11 19:04 Why do I get broken pipe on write to a pcm in state PREPARED? Anders Torger
2002-09-11 21:52 ` Tim Goetze
2002-09-12 4:06 ` Anders Torger
2002-09-12 9:08 ` Tim Goetze
-- strict thread matches above, loose matches on Subject: below --
2002-09-11 18:29 Anders Torger
2002-09-11 18:48 ` Jaroslav Kysela
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5h1y7zp5fp.wl@alsa2.suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@lists.sourceforge.net \
--cc=torger@ludd.luth.se \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.