Skip to content

Commit a41c4cb

Browse files
committed
ALSA: pcm: Make PCM linked list consistent while re-grouping
Make a common helper to re-assign the PCM link using list_move() instead of open code with manual list_del() and list_add_tail(). This assures the consistency and we can get rid of snd_pcm_group.count field -- its purpose is only to check whether the list is singular, and we can know it by list_is_singular() call now. Signed-off-by: Takashi Iwai <[email protected]>
1 parent 73365cb commit a41c4cb

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

include/sound/pcm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,6 @@ struct snd_pcm_group { /* keep linked substreams */
439439
spinlock_t lock;
440440
struct mutex mutex;
441441
struct list_head substreams;
442-
int count;
443442
};
444443

445444
struct pid;

sound/core/pcm_native.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,13 @@ static int snd_pcm_action_single(const struct action_ops *ops,
11311131
return res;
11321132
}
11331133

1134+
static void snd_pcm_group_assign(struct snd_pcm_substream *substream,
1135+
struct snd_pcm_group *new_group)
1136+
{
1137+
substream->group = new_group;
1138+
list_move(&substream->link_list, &new_group->substreams);
1139+
}
1140+
11341141
/*
11351142
* Note: call with stream lock
11361143
*/
@@ -1995,14 +2002,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
19952002
goto _end;
19962003
}
19972004
if (!snd_pcm_stream_linked(substream)) {
1998-
substream->group = group;
2005+
snd_pcm_group_assign(substream, group);
19992006
group = NULL;
2000-
list_add_tail(&substream->link_list, &substream->group->substreams);
2001-
substream->group->count = 1;
20022007
}
2003-
list_add_tail(&substream1->link_list, &substream->group->substreams);
2004-
substream->group->count++;
2005-
substream1->group = substream->group;
2008+
snd_pcm_group_assign(substream1, substream->group);
20062009
_end:
20072010
write_unlock_irq(&snd_pcm_link_rwlock);
20082011
up_write(&snd_pcm_link_rwsem);
@@ -2015,14 +2018,13 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
20152018

20162019
static void relink_to_local(struct snd_pcm_substream *substream)
20172020
{
2018-
substream->group = &substream->self_group;
2019-
INIT_LIST_HEAD(&substream->self_group.substreams);
2020-
list_add_tail(&substream->link_list, &substream->self_group.substreams);
2021+
snd_pcm_group_assign(substream, &substream->self_group);
20212022
}
20222023

20232024
static int snd_pcm_unlink(struct snd_pcm_substream *substream)
20242025
{
20252026
struct snd_pcm_substream *s;
2027+
struct snd_pcm_group *group;
20262028
int res = 0;
20272029

20282030
down_write_nonfifo(&snd_pcm_link_rwsem);
@@ -2031,16 +2033,20 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
20312033
res = -EALREADY;
20322034
goto _end;
20332035
}
2034-
list_del(&substream->link_list);
2035-
substream->group->count--;
2036-
if (substream->group->count == 1) { /* detach the last stream, too */
2036+
2037+
group = substream->group;
2038+
2039+
relink_to_local(substream);
2040+
2041+
/* detach the last stream, too */
2042+
if (list_is_singular(&group->substreams)) {
20372043
snd_pcm_group_for_each_entry(s, substream) {
20382044
relink_to_local(s);
20392045
break;
20402046
}
2041-
kfree(substream->group);
2047+
kfree(group);
20422048
}
2043-
relink_to_local(substream);
2049+
20442050
_end:
20452051
write_unlock_irq(&snd_pcm_link_rwlock);
20462052
up_write(&snd_pcm_link_rwsem);

0 commit comments

Comments
 (0)