diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-08-17 06:27:22 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-17 06:48:15 -0400 |
commit | f217ac59b6dd73105abc13da3fe656391fa6d135 (patch) | |
tree | d0ff4a0dec41b603df76baec15ec51bf62146ee6 /sound/core/control.c | |
parent | 317b80817fcaeac7ae7e062fcccef0d2aba38a78 (diff) |
sound: snd_ctl_remove_unlocked_id: simplify user control counting
Move the decrementing of the user controls counter from
snd_ctl_elem_remove to snd_ctl_remove_unlocked_id; this saves the
separate locking of the controls semaphore, and therefore removes
a harmless race.
Since the purpose of the function is to operate on user controls (the
control being unlocked is just a prerequisite), rename it to
snd_ctl_remove_user_ctl.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/control.c')
-rw-r--r-- | sound/core/control.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 9d91f77bc880..bc64b723415b 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) | |||
414 | EXPORT_SYMBOL(snd_ctl_remove_id); | 414 | EXPORT_SYMBOL(snd_ctl_remove_id); |
415 | 415 | ||
416 | /** | 416 | /** |
417 | * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it | 417 | * snd_ctl_remove_user_ctl - remove and release the unlocked user control |
418 | * @file: active control handle | 418 | * @file: active control handle |
419 | * @id: the control id to remove | 419 | * @id: the control id to remove |
420 | * | 420 | * |
@@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id); | |||
423 | * | 423 | * |
424 | * Returns 0 if successful, or a negative error code on failure. | 424 | * Returns 0 if successful, or a negative error code on failure. |
425 | */ | 425 | */ |
426 | static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, | 426 | static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file, |
427 | struct snd_ctl_elem_id *id) | 427 | struct snd_ctl_elem_id *id) |
428 | { | 428 | { |
429 | struct snd_card *card = file->card; | 429 | struct snd_card *card = file->card; |
430 | struct snd_kcontrol *kctl; | 430 | struct snd_kcontrol *kctl; |
@@ -442,6 +442,9 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, | |||
442 | goto error; | 442 | goto error; |
443 | } | 443 | } |
444 | ret = snd_ctl_remove(card, kctl); | 444 | ret = snd_ctl_remove(card, kctl); |
445 | if (ret < 0) | ||
446 | goto error; | ||
447 | card->user_ctl_count--; | ||
445 | error: | 448 | error: |
446 | up_write(&card->controls_rwsem); | 449 | up_write(&card->controls_rwsem); |
447 | return ret; | 450 | return ret; |
@@ -1053,18 +1056,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file, | |||
1053 | struct snd_ctl_elem_id __user *_id) | 1056 | struct snd_ctl_elem_id __user *_id) |
1054 | { | 1057 | { |
1055 | struct snd_ctl_elem_id id; | 1058 | struct snd_ctl_elem_id id; |
1056 | int err; | ||
1057 | 1059 | ||
1058 | if (copy_from_user(&id, _id, sizeof(id))) | 1060 | if (copy_from_user(&id, _id, sizeof(id))) |
1059 | return -EFAULT; | 1061 | return -EFAULT; |
1060 | err = snd_ctl_remove_unlocked_id(file, &id); | 1062 | return snd_ctl_remove_user_ctl(file, &id); |
1061 | if (! err) { | ||
1062 | struct snd_card *card = file->card; | ||
1063 | down_write(&card->controls_rwsem); | ||
1064 | card->user_ctl_count--; | ||
1065 | up_write(&card->controls_rwsem); | ||
1066 | } | ||
1067 | return err; | ||
1068 | } | 1063 | } |
1069 | 1064 | ||
1070 | static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) | 1065 | static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) |