summaryrefslogtreecommitdiff
path: root/sound/core/pcm.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-04-28 15:13:41 +0200
committerJaroslav Kysela <perex@suse.cz>2006-06-22 21:33:13 +0200
commit0df63e44c3e315ec0fe427ae62558231864108bd (patch)
tree3cff6f5d5fdb7ad047a61c591d891e3ca1bc669e /sound/core/pcm.c
parentf001c3acf64b8ca18fe40af592629abb261b321e (diff)
[ALSA] Add O_APPEND flag support to PCM
Added O_APPEND flag support to PCM to enable shared substreams among multiple processes. This mechanism is used by dmix and dsnoop plugins. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/pcm.c')
-rw-r--r--sound/core/pcm.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 4f5204175d37..8136be2e6066 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -829,6 +829,26 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
return -EINVAL;
}
+ if (file->f_flags & O_APPEND) {
+ if (prefer_subdevice < 0) {
+ if (pstr->substream_count > 1)
+ return -EINVAL; /* must be unique */
+ substream = pstr->substream;
+ } else {
+ for (substream = pstr->substream; substream;
+ substream = substream->next)
+ if (substream->number == prefer_subdevice)
+ break;
+ }
+ if (! substream)
+ return -ENODEV;
+ if (! SUBSTREAM_BUSY(substream))
+ return -EBADFD;
+ substream->ref_count++;
+ *rsubstream = substream;
+ return 0;
+ }
+
if (prefer_subdevice >= 0) {
for (substream = pstr->substream; substream; substream = substream->next)
if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
substream->runtime = runtime;
substream->private_data = pcm->private_data;
- substream->ffile = file;
+ substream->ref_count = 1;
+ substream->f_flags = file->f_flags;
pstr->substream_opened++;
*rsubstream = substream;
return 0;
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
- substream->file = NULL;
+
runtime = substream->runtime;
snd_assert(runtime != NULL, return);
if (runtime->private_free != NULL)