diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-04-28 09:13:41 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-06-22 15:33:13 -0400 |
commit | 0df63e44c3e315ec0fe427ae62558231864108bd (patch) | |
tree | 3cff6f5d5fdb7ad047a61c591d891e3ca1bc669e /sound/core/pcm.c | |
parent | f001c3acf64b8ca18fe40af592629abb261b321e (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.c | 25 |
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, | |||
829 | return -EINVAL; | 829 | return -EINVAL; |
830 | } | 830 | } |
831 | 831 | ||
832 | if (file->f_flags & O_APPEND) { | ||
833 | if (prefer_subdevice < 0) { | ||
834 | if (pstr->substream_count > 1) | ||
835 | return -EINVAL; /* must be unique */ | ||
836 | substream = pstr->substream; | ||
837 | } else { | ||
838 | for (substream = pstr->substream; substream; | ||
839 | substream = substream->next) | ||
840 | if (substream->number == prefer_subdevice) | ||
841 | break; | ||
842 | } | ||
843 | if (! substream) | ||
844 | return -ENODEV; | ||
845 | if (! SUBSTREAM_BUSY(substream)) | ||
846 | return -EBADFD; | ||
847 | substream->ref_count++; | ||
848 | *rsubstream = substream; | ||
849 | return 0; | ||
850 | } | ||
851 | |||
832 | if (prefer_subdevice >= 0) { | 852 | if (prefer_subdevice >= 0) { |
833 | for (substream = pstr->substream; substream; substream = substream->next) | 853 | for (substream = pstr->substream; substream; substream = substream->next) |
834 | if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) | 854 | if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) |
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
873 | 893 | ||
874 | substream->runtime = runtime; | 894 | substream->runtime = runtime; |
875 | substream->private_data = pcm->private_data; | 895 | substream->private_data = pcm->private_data; |
876 | substream->ffile = file; | 896 | substream->ref_count = 1; |
897 | substream->f_flags = file->f_flags; | ||
877 | pstr->substream_opened++; | 898 | pstr->substream_opened++; |
878 | *rsubstream = substream; | 899 | *rsubstream = substream; |
879 | return 0; | 900 | return 0; |
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, | |||
882 | void snd_pcm_detach_substream(struct snd_pcm_substream *substream) | 903 | void snd_pcm_detach_substream(struct snd_pcm_substream *substream) |
883 | { | 904 | { |
884 | struct snd_pcm_runtime *runtime; | 905 | struct snd_pcm_runtime *runtime; |
885 | substream->file = NULL; | 906 | |
886 | runtime = substream->runtime; | 907 | runtime = substream->runtime; |
887 | snd_assert(runtime != NULL, return); | 908 | snd_assert(runtime != NULL, return); |
888 | if (runtime->private_free != NULL) | 909 | if (runtime->private_free != NULL) |